/* ============================================================
   PAODO — site stylesheet
   Shared by every page. Order: tokens → base → surface →
   components → sections → responsive.

   Type is loaded in each page's <head>, not with @import here:
   an @import blocks this file from being parsed while it
   resolves, which delays every rule below it.
   ============================================================ */

/* ================= tokens ================= */
:root{
  --deep:   #3b1f6e;
  --purple: #6d4ab5;
  --line:   #e2dded;
  --ink:    #1e1b24;
  --grey:   #6b6577;
  --muted:  #9993a8;
  --white:  #ffffff;

  --f-title: 'IBM Plex Mono', ui-monospace, monospace;
  --f-body:  'Space Mono', ui-monospace, 'SF Mono', monospace;
  /* wordmark only — matches the motion intro's root sans, so the lockup on
     the site and the "PAODO" in the video are the same letterforms */
  --f-brand: 'Inter', 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', Arial, sans-serif;

  --track:    .12em;    /* caps tracking, shared by nav / metas / footer figures */
  --page-max: 1180px;
  --grid-cell: 48px;
  --band:     72px;     /* vertical gap between sections */
}

/* ================= base ================= */
*{margin:0; padding:0; box-sizing:border-box}

body{
  background:var(--white);
  color:var(--ink);
  font-family:var(--f-body);
  font-size:17px;
  line-height:1.7;
  -webkit-font-smoothing:antialiased;

  /* sticky footer: the main column takes the slack, footer pins to the bottom */
  min-height:100dvh;
  display:flex;
  flex-direction:column;

  /* containing block for the grid layer below */
  position:relative;
}

/* ================= grid surface =================
   Spans the full document, cells centred on the page,
   masked to fade out at both the top and the bottom.

   A real element rather than body::before, because the agent canvas has
   to sit on exactly the same box: one mask then fades the lattice and
   the network together, and the canvas measures itself off this. It is
   absolutely positioned, so it stays out of the body's flex flow.
   Needs <div class="grid-surface"><canvas class="grid-agents"></canvas></div>
   as the first thing in <body>. Degrades to the plain grid without
   the script. */
.grid-surface{
  position:absolute; inset:0; pointer-events:none; overflow:hidden;
  -webkit-mask-image:linear-gradient(to bottom, transparent 0%, #000 18%, #000 82%, transparent 100%);
          mask-image:linear-gradient(to bottom, transparent 0%, #000 18%, #000 82%, transparent 100%);
}
.grid-surface::before{
  content:""; position:absolute; inset:0;
  background-image:
    linear-gradient(rgba(59,31,110,.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(59,31,110,.07) 1px, transparent 1px);
  background-size:var(--grid-cell) var(--grid-cell);
  background-position:center center;
}
/* mountAgentGrid() sets the backing-store size; this is the CSS box */
.grid-agents{position:absolute; inset:0; width:100%; height:100%}

/* the one column every band aligns to */
.page{position:relative; z-index:1; width:min(var(--page-max),90%); margin:0 auto}

/* ================= brand lockup =================
   Mark + name, one component. Header and footer differ only in --brand-mark;
   the type size, the gap and the corner radius are all derived from it, so a
   lockup can never drift out of proportion.
   Needs <symbol id="paodo-mark"> present in the page. */

/* The sprite that carries that <symbol>: zero-sized and out of the flow, so it
   paints nothing itself. A class rather than style="position:absolute" because
   the Content-Security-Policy in _headers allows no inline styles. */
.mark-sprite{position:absolute}

.brand{
  --brand-mark:36px;
  /* The wordmark is set FROM the mark: its cap height equals the mark's
     height, so the two share a top and a bottom edge and the lockup reads as
     one block rather than a square with a small label next to it.
     0.727 is Inter's cap height in em — dividing by it turns the cap height
     we want into the font-size that produces it.
     --brand-cap is the share of the mark the caps take. Not 1: the round
     letters (P, O, D) overshoot the cap line top and bottom, so caps set to
     the mark's full height measure taller than the square and the wordmark
     starts to dominate it. 0.82 puts the overshoot itself flush with the
     mark's edges, which is what the eye reads as level. */
  --brand-cap:.82;
  --brand-type:calc(var(--brand-mark) * var(--brand-cap) / .727);
  --brand-gap:calc(var(--brand-mark) * .34);
  display:flex; align-items:center; gap:var(--brand-gap);
  text-decoration:none;
}
.brand-mark{
  width:var(--brand-mark); height:var(--brand-mark);
  border-radius:calc(var(--brand-mark) / 4);
  display:block; flex:none;

  /* The mark is taller than the trimmed wordmark by the overshoot allowance
     above and below. Pull that overhang out of the layout with a negative
     margin: the mark still draws at full size and still centres on the caps,
     but the lockup's BOX is now exactly the wordmark's cap box — top edge on
     the cap line, bottom edge on the baseline. That is what lets the lockup
     sit on a shared baseline with ordinary text beside it (see footer). */
  margin-block:calc(-1 * var(--brand-mark) * (1 - var(--brand-cap)) / 2);
}
/* The wordmark is the one place the site does not use the mono faces: it is
   set exactly as the motion intro sets it — Inter, 780, -0.04em — so the
   static lockup and the animated one are the same object. Weight 780 is an
   Inter variable-font instance; the <link> in each page must request the
   wght range, not fixed steps, or it snaps to 700. */
.brand-name{
  font-family:var(--f-brand);
  font-size:var(--brand-type); font-weight:780; line-height:1;
  letter-spacing:-0.04em;
  color:var(--deep);

  /* Trim the box down to the letterforms themselves — cap height on top,
     baseline underneath — so align-items:center lines the caps up with the
     mark instead of lining up the em box, which carries invisible space for
     accents and descenders PAODO does not have. Without this the wordmark
     reads as sitting slightly high.
     Older engines ignore it; Inter's em box is near-symmetric about the caps
     at line-height 1, so they land within half a pixel of the same place. */
  text-box:trim-both cap alphabetic;

  /* letter-spacing is applied after the final O too. Pull it back so the
     wordmark's right edge is the letter, keeping the lockup a clean block. */
  margin-right:-0.04em;
}
a.brand:focus-visible{outline:2px solid var(--purple); outline-offset:4px}

/* ================= atoms ================= */
.eyebrow{
  font-size:12px; font-weight:600;
  letter-spacing:.18em; text-transform:uppercase;
  color:var(--muted);
}
.eyebrow b{color:var(--purple); font-weight:600}

/* ================= header =================
   Full-bleed white band; sits above the grid layer so it reads
   as a separate surface rather than part of the sheet. */
.topbar{
  background:var(--white);
  position:relative; z-index:2;
}
.topbar .page{
  display:flex; align-items:center; padding:25px 0;
  border-bottom:1px solid var(--line);   /* on .page, so it matches the footer rule's width */
}
/* same lockup as the base, one step down, so the header sits lighter against
   the nav — one variable, the wordmark and gap follow */
.topbar .brand{--brand-mark:31px}

/* ---- nav ----
   Underline is a pseudo-element, not a border: it must not add
   height to the box, or the links sit off-centre from the logo. */
.nav{--nav-gap:24px; margin-left:auto; display:flex; align-items:center; gap:var(--nav-gap)}
/* dot separator, centred in the gap; absolute so it adds no width */
.nav a + a::before{
  content:"·";
  position:absolute; left:calc(var(--nav-gap) / -2); top:50%;
  transform:translate(-50%,-50%);
  color:var(--muted); letter-spacing:0;
  pointer-events:none;
}
.nav a{
  position:relative;
  font-family:var(--f-title);          /* same face as .brand-name; colour carries the hierarchy */
  font-size:13px; font-weight:400; line-height:1;
  letter-spacing:var(--track); text-transform:uppercase;
  color:var(--grey); text-decoration:none;
  /* same reason as the footer: the nav is set in the mono face and the
     wordmark in Inter, so their em boxes sit differently around the caps.
     Trim both to the cap box and align-items:center lines up the ink.
     It also puts the box bottom on the baseline, so the ::after underline
     below measures from the letters rather than from the descender space. */
  text-box:trim-both cap alphabetic;
}
.nav a::after{
  content:""; position:absolute; left:0; bottom:-5px;
  width:calc(100% - var(--track));     /* discount the trailing letter-space */
  height:1px; background:currentColor;
  opacity:0;
}
.nav a:hover{color:var(--deep)}
.nav a:hover::after{opacity:1}
.nav a:focus-visible{outline:2px solid var(--purple); outline-offset:4px; border-radius:2px}
.nav a:last-child{margin-right:calc(var(--track) * -1)}   /* flush the last link to the column edge */
/* Where you are: stated, and the rule stays put. "page" on the three nav
   destinations themselves; "true" on a film or post page that sits under one
   of them but is not it. Both paint the same — the distinction is for
   assistive tech, not for the eye. Matched by value rather than by presence,
   so an aria-current="false" would correctly paint nothing. */
.nav a[aria-current="page"],
.nav a[aria-current="true"]{color:var(--deep)}
.nav a[aria-current="page"]::after,
.nav a[aria-current="true"]::after{opacity:1}

/* ================= hero =================
   Homepage only. The inner pages open straight into their first
   section instead — see .section-head h1 below. */
.hero{padding:48px 0 var(--band)}
.hero h1{
  font-family:var(--f-title);
  font-size:clamp(36px,6.2vw,70px);
  line-height:1.06; letter-spacing:-0.035em;
  color:var(--deep);
  margin:24px 0 0;                 /* the gap under an eyebrow, when there is one */
  max-width:15ch;
}
.hero h1:first-child{margin-top:0} /* leading the hero: the section's own padding is the space */
.hero p{
  margin-top:32px;
  font-size:18px; line-height:1.65; color:var(--grey);
  max-width:56ch;
}
.hero p b{color:var(--deep); font-weight:600}   /* colour + weight — the one phrase that should stop the eye */

/* ================= section =================
   One rhythm everywhere: heading block, then content. */
.section{padding-bottom:var(--band)}
/* an inner page opens on a section rather than a hero, so the first one
   carries the top padding the hero would have given it */
main > .section:first-child{padding-top:48px}

.section-head{max-width:60ch; padding-bottom:32px}
.section-head h1,
.section-head h2{
  font-family:var(--f-title); font-weight:400;
  font-size:clamp(26px,3.4vw,38px);
  line-height:1.14; letter-spacing:-0.025em;
  color:var(--deep);
  margin-top:14px;
}
/* the page's own title, one per page: a step up from a section heading,
   a step down from the homepage hero */
.section-head h1{font-size:clamp(30px,4.6vw,48px); line-height:1.1; letter-spacing:-0.03em}
.section-head p{margin-top:16px; font-size:16.5px; line-height:1.65; color:var(--grey)}
.section-head a{color:var(--purple); text-decoration-thickness:1px; text-underline-offset:3px}

/* Advisory moves directly from its introduction into the editorial index;
   avoid stacking the heading-block and global section spacing here. */
.advisory-intro{padding-bottom:36px}
.advisory-intro > .section-head{padding-bottom:0}

/* ================= media =================
   16:9 frame for video. Holds its shape before anything loads,
   so the page does not jump when the file arrives. */
.media{
  position:relative;
  aspect-ratio:16/9;
  border:1px solid var(--line);
  background:var(--white);            /* opaque: lifts it off the grid layer */
  overflow:hidden;
}
.media video,
.media img{width:100%; height:100%; object-fit:cover; display:block}
/* stand-in until there is a file to point at */
.media-placeholder{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:14px; text-align:center;
  height:100%;
}
.media-placeholder .play{
  width:56px; height:56px; border-radius:50%;
  border:1px solid var(--line);
  display:grid; place-items:center;
  color:var(--purple); font-size:15px;
}

/* ================= cards =================
   One card, several uses: the homepage doors, the advisory posts.
   The whole card is the link — <a class="card">, not a card with a
   link inside it. auto-fit, so a third card needs no new rule and
   the columns collapse without a breakpoint. Set --card-min to
   change how early they wrap. */
.cards{
  --card-min:380px;
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(min(100%, var(--card-min)), 1fr));
  gap:24px;
}
.card{
  display:flex; flex-direction:column;
  background:var(--white);              /* opaque: lifts the card off the grid layer */
  border:1px solid var(--line);
  padding:36px 34px 30px;
  text-decoration:none; color:inherit;
}
a.card:hover{border-color:var(--purple)}   /* colour only — the card holds its position */
.card:focus-visible{outline:2px solid var(--purple); outline-offset:3px}

/* These cards state their edge in purple and hold it. No hover reveal: the
   affordance has to be there before the cursor is, and at rest the hairline
   was the same weight as every divider rule on the page, so the cards read
   as ruled areas rather than as objects.
   Every card outside .posts, whether or not it is a link — the homepage
   doors and the workspace plans alike. Only the advisory posts stay on the
   hairline, where a page of them would otherwise be all edge. */
.cards:not(.posts) .card{border-color:var(--purple)}

.card h2,
.card h3{
  font-family:var(--f-title);
  font-size:27px; font-weight:400; letter-spacing:-0.02em; line-height:1.15;
  color:var(--deep);
  margin:18px 0 0;
}
.card h3{font-size:21px; line-height:1.25}
.card p{margin-top:16px; font-size:16px; line-height:1.65; color:var(--grey)}

/* meta + cta share the card's baseline; margin-top:auto on the wrapper
   keeps them pinned low so all cards line up regardless of copy length */
.card-foot{margin-top:auto; padding-top:28px}
.card-meta{
  font-size:12px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--muted);
  padding-bottom:16px; border-bottom:1px solid var(--line);
}
.card-cta{
  display:flex; align-items:center; gap:10px;
  margin-top:16px;
  font-family:var(--f-title);
  font-size:13px; letter-spacing:var(--track); text-transform:uppercase;
  color:var(--deep);
}
.card-cta span{margin-left:auto}

/* The featured homepage door reverses the standard card palette. */
.cards:not(.posts) .card.card--inverse{
  background:var(--deep);
  border-color:var(--deep);
  color:var(--white);
}
.card--inverse .eyebrow,
.card--inverse .eyebrow b,
.card--inverse h2,
.card--inverse h3,
.card--inverse p,
.card--inverse .card-meta,
.card--inverse .card-cta{color:var(--white)}
.card--inverse .card-meta{border-bottom-color:rgba(255,255,255,.4)}

/* Blog index: one featured card owns the full first row, with every remaining
   story arranged in a balanced two-column grid below it. */
.cards.posts{
  display:block;
}
.posts .card{
  background:var(--white);
  border:1px solid var(--purple);
  padding:0;
}
.posts a.card:hover{border-color:var(--deep)}
.posts a.card:hover h3{text-decoration:underline; text-decoration-thickness:1px; text-underline-offset:4px}
.posts .card h3{font-weight:600}

.post-lead .post-card--featured{
  display:flex;
  flex-direction:column;
  padding:0;
}
.post-lead .post-card-copy{padding:30px 32px}
.post-card-media{
  aspect-ratio:16/9;
  overflow:hidden;
}
.post-card-media img{
  display:block;
  width:100%; height:100%;
  object-fit:cover;
  object-position:center;
}
.post-card-copy{
  display:flex;
  flex:1;
  flex-direction:column;
  padding:24px 26px;
}
.posts .post-card--featured h3{
  font-size:clamp(26px,3vw,36px);
  line-height:1.12;
}
.posts .post-card--featured p{font-size:17px}

.post-grid{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:18px;
  margin-top:18px;
}
.post-grid .card{
  padding:0;
}
.post-grid .card:not(.post-card--with-media){padding:24px}
.post-grid .post-card-media{aspect-ratio:16/9}
.post-grid .post-card-copy{padding:20px 20px 22px}
.post-grid .card h3{margin-top:10px; font-size:19px; line-height:1.22}
.post-grid .card p{margin-top:10px; font-size:14px; line-height:1.5}
.post-grid .card-foot{margin-top:auto; padding-top:18px}
.post-grid .card-meta{padding-bottom:0; border-bottom:0}
.post-grid .card-cta{display:none}

/* ================= series =================
   The capabilities, one per row: a full-width rectangle, the still on the
   left and the copy on the right, stacked top to bottom. Read as a list
   rather than a gallery — the order is the argument, each capability
   building on the one above it, and a single column is what makes that
   sequence legible. No rules between them: the rectangles are already
   hard-edged boxes on an open sheet.

   The still is a poster JPEG, never a <video>: this page carries seven of
   them and the files are megabytes each. The video itself loads only on
   the film's own page. */
.series{
  list-style:none;
  display:grid;
  grid-template-columns:1fr;
  gap:20px;
}
/* the <li> is the grid cell and stretches; the card fills it */
.series li{display:flex}
.film{
  flex:1;
  /* The still sets the row's height and the copy sits beside it. 40% keeps
     a 16:9 frame big enough to read at the page's full width while leaving
     the text a comfortable measure. */
  display:grid;
  grid-template-columns:minmax(0, 40%) minmax(0, 1fr);
  background:var(--white);              /* opaque: lifts the card off the grid layer */
  /* purple on every film, shot or not, so the set reads as one column of
     objects. What separates them is the still: a film that exists shows its
     frame, one that does not says so. */
  border:1px solid var(--purple);
  text-decoration:none; color:inherit;
}
a.film:hover{border-color:var(--deep)}
a.film:focus-visible{outline:2px solid var(--purple); outline-offset:3px}

/* flush to the card's left edge — the card supplies the frame, so a second
   border around the still would just double the line. No rule on the inside
   edge either: the still's own hard edge is already the division, and a
   hairline on top of it only adds weight. */
.film-still{
  position:relative; aspect-ratio:16/9;
  align-self:center;
  overflow:hidden;
}
.film-still img{width:100%; height:100%; object-fit:cover; display:block}

/* Three fixed zones: title at the top, description centred in the available
   space, and CTA at the bottom. Equal vertical padding gives the title and
   CTA the same distance from their respective card edges. */
.film-body{
  display:grid;
  grid-template-rows:auto 1fr auto;
  min-height:240px;
  padding:26px 30px;
}
/* the label is the heading — a caps line rather than a title, so the still
   stays the loudest thing in the row */
.film-label{
  font-family:var(--f-title); font-weight:400;
  font-size:13px; letter-spacing:var(--track); text-transform:uppercase;
  color:var(--deep);
}
.film-label b{color:var(--muted); font-weight:400}   /* the number sits back */
.film p{
  align-self:center;
  margin-top:0;
  font-size:14.5px; line-height:1.6; color:var(--grey); max-width:56ch;
}

/* Same shape as .card-cta — one gesture for "there is a page behind this"
   across the whole site. The rule above it separates the promise from the
   description without adding a second box. */
.film-cta{
  display:flex; align-items:center; gap:10px;
  margin-top:0; padding-top:0;
  font-family:var(--f-title);
  font-size:13px; letter-spacing:var(--track); text-transform:uppercase;
  color:var(--deep);
}
.film-cta span{margin-left:auto}
/* the arrow steps forward on hover; nothing else moves, so the row holds
   its position */
a.film:hover .film-cta span{transform:translateX(4px)}
.film-cta span{transition:transform .15s ease}
@media (prefers-reduced-motion:reduce){.film-cta span{transition:none}}

/* Not shot yet: it keeps its place so the set reads as a whole, but it is
   not a link, and the empty frame says so rather than faking a thumbnail. */
.is-upcoming .film{cursor:default}
.is-upcoming .film-still{display:grid; place-items:center}
.is-upcoming .film-still .eyebrow{color:var(--muted)}
.is-upcoming .film-label{color:var(--grey)}
.is-upcoming .film-cta{color:var(--muted)}
.film-label--purple,
.film-label--purple b{color:var(--deep)}

/* ================= film nav =================
   Previous / next through the series. Every film page offers the two either
   side of it rather than a way back to an index: the set is a sequence, and
   the useful next move is almost always the next film. */
.filmnav{
  border-top:1px solid var(--line);
  margin-top:36px; padding-top:22px;
  display:flex; gap:16px 24px; flex-wrap:wrap;
}
.filmnav a{
  display:block; max-width:44ch;
  text-decoration:none; color:inherit;
}
.filmnav .next{margin-left:auto; text-align:right}
.filmnav .eyebrow{color:var(--muted)}
.filmnav b{
  display:block; margin-top:8px;
  font-family:var(--f-title); font-weight:400;
  font-size:17px; letter-spacing:-0.015em; color:var(--deep);
}
.filmnav a:hover b{text-decoration:underline; text-decoration-thickness:1px; text-underline-offset:3px}
.filmnav a:focus-visible{outline:2px solid var(--purple); outline-offset:4px}

/* ================= prose =================
   Blog posts use the site's mono face for structure and a proportional face
   for sustained reading. The white reading surface quiets the blueprint
   without turning the article into a bordered card. */
article.section{
  width:min(880px,100%);
  margin-inline:auto;
  background:var(--white);
  box-shadow:0 0 30px 26px var(--white);
}
article.section > .section-head{
  width:100%; max-width:none;
  margin-inline:auto; padding-bottom:48px;
  border-bottom:1px solid var(--line);
  text-align:center;
}
article.section > .section-head h1{
  max-width:18ch;
  margin-inline:auto;
  font-weight:600;
}
article.section > .section-head p{
  max-width:58ch;
  margin-inline:auto;
  font-size:17px; line-height:1.7;
}

.prose{
  max-width:62ch;
  margin:56px auto 0;
  padding-bottom:var(--band);
  font-size:17px; line-height:1.75;
}
.prose p{
  text-align:justify;
  hyphens:auto;
  -webkit-hyphens:auto;
}
.prose > * + *{margin-top:24px}
.prose > .post-hero{
  width:min(880px,90vw);
  margin-left:50%;
  transform:translateX(-50%);
}
.post-hero img{
  display:block;
  width:100%; height:auto;
}
.prose h2{
  border-top:1px solid var(--line);
  padding-top:24px;
  font-family:var(--f-title); font-weight:600;
  font-size:28px; line-height:1.2; letter-spacing:-0.025em;
  color:var(--deep);
  margin-top:68px;
}
.prose > h2:first-child{
  margin-top:0;
  border-top:0;
  padding-top:0;
}
.prose > .post-hero:first-child + h2{
  margin-top:56px;
  border-top:0;
  padding-top:0;
}
.prose ul{
  padding-left:24px;
}
.prose li + li{margin-top:10px}
.prose a{color:var(--purple); text-decoration-thickness:1px; text-underline-offset:3px}
.prose blockquote{
  border-left:2px solid var(--line);
  padding-left:22px;
  color:var(--grey);
}

/* ================= footer ================= */
.page-foot{margin-top:auto}
footer{
  border-top:1px solid var(--line);
  padding:30px 0;
  display:flex; gap:14px 24px; flex-wrap:wrap;
  line-height:1;
  /* one axis: the mark, PAODO, the meta and the date all centre on it */
  align-items:center;
}
/* Trim each item to its letterforms — cap height to baseline — so what gets
   centred is the ink, not the em box, which carries different amounts of
   empty ascender/descender space in each of the faces used here. The mark
   needs no trim: it is exactly its own height, and it is already centred
   on the wordmark's caps by the lockup itself. */
footer .eyebrow{text-box:trim-both cap alphabetic}
footer .eyebrow a{color:inherit; text-decoration:none}
footer .eyebrow a:hover{text-decoration:underline; text-underline-offset:3px}
footer .eyebrow a:focus-visible{outline:2px solid var(--purple); outline-offset:4px; border-radius:2px}
/* same lockup as the header, scaled down so the footer echoes it rather than
   repeating it — one variable, the wordmark and gap follow */
footer .brand{--brand-mark:24px}

/* ================= responsive ================= */
@media (max-width:760px){
  :root{--band:48px}

  /* centred header, two rows: mark + name together, nav beneath */
  .topbar .page{flex-wrap:wrap; justify-content:center; row-gap:14px; padding:22px 0}
  .topbar .brand{--brand-mark:28px}
  .nav{--nav-gap:20px; margin-left:0; width:100%; justify-content:center}
  .nav-brand{display:none}
  /* drop the desktop flush-right nudge: with the row centred there is
     no column edge to align to, and the negative margin just skews it */
  .nav a:last-child{margin-right:0}

  .hero{padding:28px 0 var(--band)}
  /* the header is already a centred stack at this width, so the hero opens
     the same way — the whole block centres on one axis: eyebrow, title,
     body copy. */
  .hero .eyebrow{
    text-align:center;
    /* .18em of tracking is applied after the last letter too. Push the line
       back by half of it so what centres is the lettering, not the box —
       the same correction the nav makes. */
    text-indent:.09em;
  }
  .hero h1{
    text-align:center;
    margin-inline:auto;      /* max-width:15ch is narrower than the column */
  }
  .hero p{
    margin-top:24px; font-size:16.5px;
    text-align:justify;
    margin-inline:auto;      /* max-width:56ch, in case the column ever gets there */
    /* Space Mono is fixed-pitch, so justification can only stretch the word
       spaces — it cannot compress the letters to help. On a phone column
       that is few enough words per line to open real gaps, so let the
       words break instead. <html lang="en"> is what makes this work. */
    hyphens:auto;
    -webkit-hyphens:auto;
  }
  main > .section:first-child{padding-top:28px}

  /* no room for a still beside the copy: the rectangle keeps its place in
     the column but stacks internally — frame on top, copy under it */
  .series{gap:16px}
  .film{grid-template-columns:1fr}
  .film-body{padding:22px 24px}
  .film p{font-size:14px}
  .film-cta{padding-top:0}
  .filmnav{display:grid; grid-template-columns:1fr; gap:20px}
  .filmnav .next{margin-left:0; text-align:left}

  .cards{gap:16px}
  .card{padding:30px 26px 26px}
  .card h2{font-size:24px}
  .card p{font-size:15.5px}
  .card-foot{padding-top:24px}

  .cards.posts{display:block}
  .post-lead .post-card--featured{
    display:flex;
    padding:0;
  }
  .post-lead .post-card-copy{padding:22px 24px}
  .posts .post-card--featured h3{font-size:28px}

  .post-grid{grid-template-columns:1fr; gap:16px; margin-top:16px}
  .post-grid .card,
  .post-grid .card:first-child,
  .post-grid .card:last-child{
    padding:0;
  }
  .post-grid .card:not(.post-card--with-media){padding:20px}
  .post-grid .post-card--with-media{
    display:flex;
    flex-direction:column;
  }
  .post-grid .post-card-copy{padding:18px}
  .post-grid .card h3{font-size:18px}
  .post-grid .card-foot{padding-top:14px}

  article.section > .section-head{
    padding-bottom:32px;
    text-align:left;
  }
  article.section > .section-head h1,
  article.section > .section-head p{max-width:none; margin-inline:0}
  article.section > .section-head p{font-size:17px; line-height:1.65}
  .prose{
    max-width:none;
    margin-top:36px;
    font-size:17px; line-height:1.7;
  }
  .prose h2{
    margin-top:56px;
    padding-top:20px;
    font-size:24px;
  }
  .prose > .post-hero:first-child + h2{
    margin-top:36px;
    padding-top:0;
  }
}

/* ================= print ================= */
@media print{
  body{zoom:.68; display:block; min-height:0}  /* viewport height is meaningless on paper */
  .grid-surface{display:none}
  .media{display:none}
}
