/* ==========================================================================
   KodeYak — the hero aperture
   Chunk 3 of the rebuild: the display screen, the closing rail, and the
   geometry that keeps them registered. Self-contained like scene.css and
   nav.css. Colour and motion come from tokens.css — never a raw hex here.

   THE IDEA. The masthead is a HUD rail welded to the top of the screen. This
   adds its twin at the bottom of a fixed band of artwork, with a glass display
   panel standing directly on it. The artwork and the panel are PINNED; the rail
   is the leading edge of the paper and rides UP as you scroll. So the two rails
   converge and shut the artwork like an aperture, and when they meet, the page
   is on paper.

   Both shapes are drawn from assets/img/Screen.svg and assets/img/Rail.svg.
   Where this file and those files disagree, the files win — re-measure rather
   than nudge.

   No JavaScript, no scroll listener, no transform. The whole effect is one
   fixed layer plus one in-flow element, which means it cannot jank, cannot
   drift out of sync with the scroll position, and degrades to "a hero image
   with a bar under it" if anything at all goes wrong.
   ========================================================================== */

/* ---- The band -------------------------------------------------------------
   How tall the hero is, and the only place that decides it. The natural height
   is the chosen cut's own aspect (--ky-hero-aspect, written onto <html> by
   page.njk from src/_data/scene.js), so the whole composition shows with no
   crop — swapping the cut reshapes the hero with no edit here.

   Clamped at both ends, and both ends have a job. The MAX keeps paper on screen
   at first paint: that is the entire point of the short cut, and a 2.18:1 band
   on a 1920px monitor would otherwise be 880px tall and eat the fold again. The
   MIN stops narrow windows letterboxing — at 390px the natural band is 179px,
   which is a smear with nowhere to put the panel. Below the min the band stops
   matching the artwork and the image starts cropping horizontally instead; see
   --ky-hero-focus in scene.css for which way.                                 */
:root {
  --ky-hero-band: clamp(
    var(--ky-hero-band-min, 56dvh),
    calc(100vw / (var(--ky-hero-aspect, 1920 / 880))),
    var(--ky-hero-band-max, 74dvh)
  );
}

/* ---- Shared geometry ------------------------------------------------------
   MEASURED OFF THE DESIGN FILES, not eyeballed. assets/img/Screen.svg and
   assets/img/Rail.svg carry the authored outlines; the numbers below are their
   proportions, and the derivation is recorded so a re-cut can be re-measured
   rather than re-guessed. Both files are working artwork and stay out of the
   build — nothing here loads them, they are the spec, not an asset.

   NOTHING IS ROUNDED. Every corner in both files is a chamfer, and on the panel
   every chamfer is exactly 45 degrees. That is the house rule for tech surfaces
   and it is not a stylistic preference to be softened later: rounded corners
   were briefly on the panel's top edge and they read as a different family of
   object from the masthead sitting directly above them.

   THE PANEL SITS ON THE RAIL. It had feet, and struts before that, both of them
   inventions to bridge a gap that should never have existed. The panel's bottom
   edge IS the rail's plinth top. That also removes the last thing that could
   fall out of register: there is no clearance to keep constant, so there is
   nothing to keep constant.

   SCREEN, from Screen.svg (900 x 467 outline): four 45-degree chamfers, of
   which THREE are kept — the bottom-left is squared, see the polygon. Three
   small at 14 units — 1.56% of the width — and the bottom-right at 93.4, which
   is 10.37%. Kept proportional so the panel's silhouette is the same shape at
   any width, clamped so the small cuts cannot vanish on a phone or bloat on a
   wide screen.

   RAIL, from Rail.svg (1922 x 118 outline): FOUR levels, not three, read left
   to right as a short stub, the tall plinth, a short run, then a medium step
   out to the right edge. Heights as multiples of the short level: plinth 2.081,
   medium 1.676. Anchoring short to --mh-short is what ties the whole thing to
   the masthead — and it is very close to the file's own intent, since at the
   file's natural scale across a 1440px window the short level lands at 42px
   against the masthead's 44.

   THE TWO SHAPES SHARE THEIR CORNERS. This is the point of the whole thing and
   it drives every number below. The panel's bottom edge runs from its square
   bottom-left corner to the foot of its big bottom-right chamfer; the rail's
   plinth spans EXACTLY that same range. So at each end, the panel's cut
   and the rail's cut spring from one shared point — a node — and the two
   silhouettes read as one assembly seated on a common grid rather than two
   shapes that happen to be stacked.

   Everything is therefore derived from --hr-node-l and --hr-node-r, and nothing
   is a nudge. The earlier version put the rail's steps at "the panel's right
   edge plus 48px", which looked deliberate at one width and drifted at every
   other one, because 48px is not a fact about anything.

   ONE ANGLE, 45 degrees, everywhere. Screen.svg cuts all four of its corners at
   45 (we keep three of them) and Rail.svg does not — its chamfers measure 0.82 and 1.57 run per rise.
   Those are equalised here on purpose: two cuts can only meet cleanly at a node
   if they agree about what a cut is, and the panel is the shape with the
   authoritative geometry. (One exception, forced: see --hr-c1.)               */
:root {
  --sc-inset: max(var(--ky-gutter), calc((100vw - var(--ky-content-max)) / 2));
  --sc-width: min(660px, calc(100vw - var(--ky-gutter) * 2));
  --sc-cut: clamp(9px, calc(var(--sc-width) * 0.0156), 15px);      /* 1.56%  */
  --sc-bigcut: clamp(46px, calc(var(--sc-width) * 0.1037), 88px);  /* 10.37% */
  --sc-g: 1.5px;         /* the lit edge's thickness — see __edge below       */

  --hr-short: var(--mh-short);              /* the masthead's own thickness   */
  --hr-mid: calc(var(--hr-short) * 1.676);  /* the step at the right end      */
  --hr-tall: calc(var(--hr-short) * 2.081); /* the plinth, under the panel    */
  --hr-step-run: clamp(140px, 16vw, 300px); /* how long the short run holds   */

  /* THE NODES: the two points where the panel's bottom edge meets the rail.
     Both are read straight off the panel's own outline, so they cannot drift.

     The left node is the panel's LEFT EDGE, not a chamfer foot, because that
     corner is square — so the plinth begins exactly where the panel's left face
     comes down. Still derived, still not a nudge; the outline it is read from
     simply changed shape. See the polygon below.                              */
  --hr-node-l: var(--sc-inset);
  --hr-node-r: calc(var(--sc-inset) + var(--sc-width) - var(--sc-bigcut));

  /* Chamfer runs. At 45 degrees a run IS its rise, so these are just the level
     differences — which is the tidiest possible statement of "one angle".

     --hr-c1 is the exception, and it is forced rather than chosen. Its chamfer
     has to FINISH at the left node, so it needs --hr-rise of room to the left
     of it; below about 1290px the content column hits the gutter, the node sits
     ~34px from the edge, and there is physically nowhere to put a 48px run.
     min() lets that one cut steepen instead. Losing the angle there is the
     lesser loss: an off-angle chamfer is a detail, a missed node is the idea. */
  --hr-rise: calc(var(--hr-tall) - var(--hr-short));
  --hr-c1: min(var(--hr-rise), var(--hr-node-l));
  --hr-c2: var(--hr-rise);
  --hr-c3: calc(var(--hr-mid) - var(--hr-short));

  /* The plinth runs node to node; the stub is whatever is left to the left of
     it, and the last step follows the second node out to the right. */
  --hr-stub: calc(var(--hr-node-l) - var(--hr-c1));
  --hr-step-a: var(--hr-node-r);
  --hr-step-b: min(
    calc(100vw - var(--hr-c3)),
    calc(var(--hr-step-a) + var(--hr-c2) + var(--hr-step-run))
  );
}

/* ---- The stage ------------------------------------------------------------
   .ky-hero is a spacer and nothing else — the artwork and the panel are both
   pinned, so neither contributes height. Its ONE job is to hold the paper off
   the top of the document for exactly one band, less the rail, so the rail
   starts docked at the band's bottom edge with the panel sitting on it.

   .ky-hero-stage is the same band as a positioned box, so everything pinned
   inside it can be placed against the BAND rather than against the viewport.
   Without it the panel would need `bottom: calc(100dvh - band + …)`, which is
   the same number written in a way nobody can check.

   dvh, NOT svh, and this is the one place in the project where that is right.
   `position: fixed` resolves against the viewport as it is RIGHT NOW, so the
   band tracks the URL bar. If the spacer were sized in svh it would not, and
   collapsing the bar on a phone would slide the rail out from under the panel
   by the height of the bar. dvh moves with the same thing `fixed` moves with, so
   the joint holds.                                                            */
.ky-hero {
  position: relative;
  height: calc(var(--ky-hero-band) - var(--hr-tall));
}

/* pointer-events: the stage spans the whole band and would otherwise swallow
   every click on the artwork; the panel turns them back on for itself. */
.ky-hero-stage {
  position: fixed;
  inset: 0 0 auto;
  height: var(--ky-hero-band);
  z-index: 0;
  pointer-events: none;
}

/* ---- The display panel ----------------------------------------------------
   Pinned to the stage, so the rail closes over it rather than carrying it
   away. Its box bottom is the plinth's top — tucked 2px under, so the panel's
   bottom hairline and the rail's top hairline resolve to ONE line instead of
   two adjacent ones. The rail paints later, so the rail's edge is the one that
   survives, which is right: it is the moving part.

   z-index 0 on the stage, deliberately, not 1. It has to sit ABOVE the artwork
   (-1) and BELOW everything that closes over it. The rail and .ky-paper are
   positioned with z-index auto and come later in the document, so at 0 they
   paint over it in tree order for free; at 1 the panel would jump the queue and
   stay visible through the paper for the rest of the page.                     */
.ky-screen {
  position: absolute;
  left: var(--sc-inset);
  bottom: calc(var(--hr-tall) - 2px);   /* box bottom = the plinth's top */
  width: var(--sc-width);
  pointer-events: auto;
  /* THE SCALE HAS NO 5 AND NO 10. It runs 1,2,3,4,6,8,12,16,24,32 — see
     tokens.css. This was written against --ky-space-10 first, and an undefined
     custom property does not fall back to the clamp's minimum: it makes the
     WHOLE declaration invalid at computed-value time, so `padding` reset to 0.
     Silently. The panel rendered with its copy hard against the glass and the
     buttons sliced off by the outline, which looks like a clip-path bug and is
     not one. If a box here loses its padding for no reason, check the token
     exists before touching anything else. */
  padding: clamp(var(--ky-space-6), 2.4vw, var(--ky-space-8));
  color: var(--ky-bone-100);
}

/* ONE SILHOUETTE, TWO LAYERS. A rectangle with THREE corners cut at 45 degrees
   — two small, the bottom-right large — and the bottom-left square. The whole
   outline is a single closed polygon, so the lit edge traces every face of it
   including the diagonals, which a border cannot do.

   THE HAIRLINE MUST BE THE SAME WIDTH ON THE DIAGONALS AS ON THE STRAIGHTS,
   and getting that right is the whole reason these two layers do not share a
   clip-path. Inflating __edge's BOX by --sc-g on all sides — the obvious move,
   and what this did first — widens the straight faces by exactly g but shifts a
   45-degree face by (g, g), which is a perpendicular offset of g·√2. The big
   bottom-right chamfer therefore came out 41% heavier than the rest of the
   outline: on a 68px cut that is plainly visible, and it read as a thick border
   on one corner rather than as a hairline round a panel.

   So the EDGE keeps the true outline at inset 0, and the PANEL is inset by g
   with its cuts shortened to match. For a 45-degree chamfer, offsetting every
   face inward by d shortens the cut by d(2 - √2) — the 0.586 below. Now every
   face, diagonal or not, is exactly --sc-g of edge.

   Read the points as: down the top-left cut, across the top, down the
   top-right cut, down the right, down the big bottom-right cut, along the
   bottom to the SQUARE bottom-left corner, and home up the left edge.

   THE BOTTOM-LEFT IS SQUARE, AND IT IS A DEVIATION FROM Screen.svg — which cuts
   all four. Two chamfers met there within about 10px of each other: the panel's
   own small cut, and the rail's stub-to-plinth cut immediately below and left of
   it. At the scale they render, that did not read as two deliberate corners, it
   read as one corner that could not decide. Squaring this one leaves the panel's
   left edge running straight down onto the plinth, and the rail's chamfer is
   then the only diagonal in that area — so it reads as the deliberate one.
   Changed 2026-09-15; the other three cuts are untouched. Re-measuring against
   Screen.svg is still right for everything else on this outline.               */
.ky-screen__edge,
.ky-screen__panel {
  position: absolute;
  pointer-events: none;
  clip-path: polygon(
    var(--sc-c) 0,
    calc(100% - var(--sc-c)) 0,
    100% var(--sc-c),
    100% calc(100% - var(--sc-cb)),
    calc(100% - var(--sc-cb)) 100%,
    0 100%,
    0 var(--sc-c)
  );
}
/* The edge carries the TRUE outline — its chamfer feet are the nodes the rail
   is built from, so this layer is the one that must not be offset. */
.ky-screen__edge {
  inset: 0;
  --sc-c: var(--sc-cut);
  --sc-cb: var(--sc-bigcut);
}
.ky-screen__panel {
  inset: var(--sc-g);
  --sc-c: calc(var(--sc-cut) - var(--sc-g) * 0.586);
  --sc-cb: calc(var(--sc-bigcut) - var(--sc-g) * 0.586);
}

/* Lit from the RIGHT, because that is where the artwork's light is — the dome
   and the lit paper are right of frame and the void is left, so a highlight on
   the left would be lit by nothing. Same reasoning, same direction, as nav.css.

   The FLOOR is up. Screen.svg draws this outline as a flat bone at .8, so the
   gradient's dim end was reading as a break in a line the file intends to be
   continuous. Keeping the direction and raising the low end is the compromise:
   the system's light still comes from the right, and the hairline still goes
   all the way round. */
.ky-screen__edge {
  background: linear-gradient(105deg,
    rgba(var(--ky-rgb-gridlit), .42) 0%,
    rgba(var(--ky-rgb-gridlit), .56) 44%,
    rgba(var(--ky-rgb-bone), .70) 78%,
    rgba(var(--ky-rgb-bone), .82) 100%);
}

/* Abyss over artwork, never Ink — Ink is the deepest step and reads as a black
   box sitting on the picture rather than as glass in front of it. Only the
   alpha moves, so the depth is one colour at two densities.

   THE ALPHAS ARE SET BY MEASUREMENT, and the measurement is taken OFF THE
   RENDERED PAGE, not off a model of it. That distinction cost a round: a
   gaussian-blur simulation of this gradient predicted 7.40:1, and the browser
   delivered 6.82:1 for the same numbers. The gap is `saturate(115%)` on the
   backdrop-filter, which brightens the artwork bleeding through and which no
   convolution model was accounting for. Screenshot the page with the copy set
   to `visibility: hidden`, sample the glass, and compare against the text
   colour; anything else flatters the result.

   Measured that way, worst pixel, against the panel's own copy — all bone-100,
   since .ky-glass sets the inherited colour:

       .94 / .88 / .78    ~9.6:1     where this started, and far too solid
       .84 / .79 / .70     7.96:1  <- shipping, where the copy actually sits
                           6.94:1     at the far corner of the content box
       .80 / .74 / .62     6.82:1     one step more glass, drops out of AAA

   So the floor is not aesthetic. A further step is perfectly legible and clears
   AA with room, but it gives up the AAA the rest of the system holds, and that
   is a decision rather than a nudge.

   The 6.94 figure is the extreme bottom-right of the CONTENT BOX, past the copy
   and inside the big chamfer's approach. Nothing sits there today — the
   paragraph is 46ch and the buttons are left-aligned — but the padding does not
   know about the chamfer, so a full-width element added here would run into
   both the low end of the gradient and the cut corner at once. */
.ky-screen__panel {
  background:
    radial-gradient(120% 160% at 100% 0%, rgba(var(--ky-rgb-bone), .06), transparent 56%),
    linear-gradient(118deg,
      rgba(var(--ky-rgb-panel), .84) 0%,
      rgba(var(--ky-rgb-panel), .79) 58%,
      rgba(var(--ky-rgb-panel), .70) 100%);
  -webkit-backdrop-filter: blur(16px) saturate(115%);
          backdrop-filter: blur(16px) saturate(115%);
}

.ky-screen__body { position: relative; z-index: 1; }
.ky-screen p { max-width: 46ch; margin: var(--ky-space-4) 0 var(--ky-space-6); }
.ky-screen .ky-actions { display: flex; gap: var(--ky-space-3); flex-wrap: wrap; }

/* ---- The closing rail -----------------------------------------------------
   In NORMAL FLOW between the hero spacer and the paper, which is the whole
   trick: it rises because the document rises, at exactly the document's speed,
   with nothing to keep in sync.

   Its box is --hr-tall — the plinth, the tallest level — and the other two
   levels are cut out of the top by the outline below.                          */
.ky-hero-rail {
  position: relative;
  z-index: 1;
  height: var(--hr-tall);
}

/* FOUR levels, left to right, as Rail.svg draws them: a SHORT stub at the
   extreme left, up a chamfer to the TALL plinth that carries the panel, down a
   chamfer to a SHORT run, and up a last chamfer to the MID step that reaches
   the right edge.

   THE PLINTH IS EXACTLY THE PANEL'S FOOTPRINT — node to node. Its two chamfers
   therefore start where the panel's own chamfers land, so each end reads as one
   corner shared by two shapes rather than two corners near each other.

   The stub is the detail that makes the rest read. Without it the plinth starts
   flush at the left edge and the whole bar looks like one block with some
   notches cut in the right-hand end; with it, the bar reads as a machined
   profile that happens to be tall where the panel needs it.

   It also ends MID rather than short — the rail does not taper away, it steps
   back up. That is what stops the right-hand end reading as leftovers.

   Extra room ABOVE the box, the mirror of the masthead's extra room below:
   clip-path clips and never expands, so the grown edge needs somewhere to be or
   the hairline is cut off flush at the top of each level.                       */
.ky-hero-rail__edge,
.ky-hero-rail__panel {
  position: absolute;
  inset: -8px 0 0;
  pointer-events: none;
  clip-path: polygon(
    0 calc(8px + var(--hr-tall) - var(--hr-short) - var(--hr-grow, 0px)),
    var(--hr-stub) calc(8px + var(--hr-tall) - var(--hr-short) - var(--hr-grow, 0px)),
    calc(var(--hr-stub) + var(--hr-c1)) calc(8px - var(--hr-grow, 0px)),
    var(--hr-step-a) calc(8px - var(--hr-grow, 0px)),
    calc(var(--hr-step-a) + var(--hr-c2)) calc(8px + var(--hr-tall) - var(--hr-short) - var(--hr-grow, 0px)),
    var(--hr-step-b) calc(8px + var(--hr-tall) - var(--hr-short) - var(--hr-grow, 0px)),
    calc(var(--hr-step-b) + var(--hr-c3)) calc(8px + var(--hr-tall) - var(--hr-mid) - var(--hr-grow, 0px)),
    100% calc(8px + var(--hr-tall) - var(--hr-mid) - var(--hr-grow, 0px)),
    100% 100%,
    0 100%
  );
}

/* Lit from the right, like every other edge in the system. This one is the
   blade's leading edge — the line that travels up the artwork — so it runs a
   touch hotter than the masthead's. */
.ky-hero-rail__edge {
  --hr-grow: 1.5px;
  background: linear-gradient(90deg,
    rgba(var(--ky-rgb-gridlit), .26) 0%,
    rgba(var(--ky-rgb-gridlit), .42) 42%,
    rgba(var(--ky-rgb-bone), .58) 76%,
    rgba(var(--ky-rgb-bone), .74) 100%);
}

/* Sheen anchored bottom-right rather than top-right: this rail is lit from the
   paper side, being the piece that hands over to it. */
.ky-hero-rail__panel {
  background:
    radial-gradient(120% 180% at 100% 100%, rgba(var(--ky-rgb-bone), .055), transparent 58%),
    linear-gradient(0deg, rgba(var(--ky-rgb-panel), .86), rgba(var(--ky-rgb-panel), .79));
  -webkit-backdrop-filter: blur(14px) saturate(115%);
          backdrop-filter: blur(14px) saturate(115%);
}

/* The hand-over line. A hairline in the warm accent along the rail's underside,
   right where the glass gives way to paper — the seam the old band fade was
   trying and failing to hide, drawn deliberately instead of apologised for.

   DECORATIVE ONLY. It marks a boundary; it never signals state, which stays
   the rule for the accent everywhere else in the system. */
.ky-hero-rail::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 2px;
  background: linear-gradient(90deg,
    rgba(var(--ky-rgb-fiber), .85) 0%,
    rgba(var(--ky-rgb-fiber), .55) 62%,
    rgba(var(--ky-rgb-fiber), .22) 100%);
}

/* The eyebrow is CENTRED ON THE PLINTH — the raised section, node to node,
   which is exactly the panel's own footprint. Left-aligned at the gutter it read
   as a stray label parked in a corner; centred on the step it reads as that
   step's caption, and it lines up under the panel that shares those two nodes.

   Positioned from the nodes rather than given a width, so it re-centres itself
   whenever the panel does. Vertically it centres in --hr-tall, the plinth's own
   height — same idea as the masthead centring its lockup in the shoulder and
   its nav in the rail rather than in one shared row. */
.ky-hero-rail__inner {
  position: absolute;
  top: 0;
  left: var(--hr-node-l);
  width: calc(var(--hr-node-r) - var(--hr-node-l));
  z-index: 1;
  height: var(--hr-tall);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Fiber, not the cool accent the eyebrow takes everywhere else. This label is
   the one warm mark in a composition that is otherwise steel and wood, and it
   is the line that has to survive the rail passing over lit artwork.

   The colour goes on the SPAN. weave.css paints `.ky-eyebrow .l` muted, which
   is a more specific selector than `.ky-eyebrow`, so setting it on the <p> is
   silently overridden — it rendered as paper-muted ink on glass, near enough
   invisible, and looked like the token was wrong rather than the selector. */
.ky-hero-rail .ky-eyebrow { margin: 0; font-size: var(--ky-text-small); }
.ky-hero-rail .ky-eyebrow .l { color: var(--ky-fiber-400); }

/* ---- Retiring the pinned stage --------------------------------------------
   The panel is fixed, so once the rail has closed over it, it is INVISIBLE BUT
   STILL THERE — and its two buttons are still in the tab order. A keyboard user
   would tab from the footer links into a pair of controls nobody can see.

   Where scroll-driven animation exists, this hides it for real at the moment
   the aperture shuts. Where it does not (Firefox at time of writing), the panel
   stays reachable — the same as any fixed element covered by content, and the
   reason both its links are duplicated in the footer. Not a substitute for
   testing it: see docs/STATUS.md.

   visibility animates discretely, flipping at the midpoint between keyframes,
   so the 99%/100% pair puts the flip effectively at the end of the range. */
@supports (animation-timeline: scroll()) {
  @keyframes ky-stage-retire {
    0%, 99% { visibility: visible; }
    100%    { visibility: hidden; }
  }
  .ky-hero-stage {
    animation: ky-stage-retire linear both;
    animation-timeline: scroll(root block);
    animation-range: 0 calc(var(--ky-hero-band) - var(--hr-tall) - var(--hr-short));
  }
}

/* ---- Narrow screens -------------------------------------------------------
   The profile stops earning its keep once the panel is full-bleed: the plinth
   is then the whole width, and a step that spans everything is not a step.
   Collapsing the four levels to one turns the outline into a plain rectangle
   without needing a second one — the chamfer runs fall out to 0 on their own,
   because each is a rise times a slope and the rises are now all zero.

   The panel's own chamfers stay. They are its identity, not its decoration.   */
@media (max-width: 720px) {
  :root {
    /* A TALLER BAND, not a shorter one, and that is not a contradiction. The
       short cut exists to get paper above the fold, and on a phone it does that
       far too well: at 56dvh the band is 473px, the panel is ~360px of it and
       the masthead another 56, which leaves about 50px of artwork on screen.
       The hero stops being a hero. 70dvh puts ~140px of picture above the panel
       on a 844px screen and still leaves a quarter of the viewport on paper.

       On a genuinely short phone (667px) this is tight — the panel ends up just
       under the masthead with no strip above it. There is no third option at
       that size; something has to give, and it should not be the copy. */
    --ky-hero-band-min: 70dvh;
    --hr-short: 56px;
    --hr-mid: var(--hr-short);
    --hr-tall: var(--hr-short);
    --hr-stub: 0px;
    --hr-step-a: 100%;
    --hr-step-b: 100%;
  }
  /* Every pixel taken back here is a pixel of artwork on a phone. */
  .ky-screen { padding-block: var(--ky-space-4); }
}

/* SHORT VIEWPORTS. The band is capped at 74dvh, and on a landscape phone that
   is about 250px to fit a masthead, a panel and a rail into. Tighten the panel
   rather than let it grow past the masthead, where it would be clipped from the
   top with the headline inside the clipped part. */
@media (max-height: 620px) {
  .ky-screen { padding-block: var(--ky-space-4); }
  .ky-screen p { margin-block: var(--ky-space-3) var(--ky-space-4); }
}
