/* Shared styles for the moments layout: subject sections, bands, verbs, quiet build. */

    /* a phone, drawn to the app's own tokens (page_bg 13 42 30 · card 18 54 39 ·
       bright 52 211 153 · paper 245 244 240 · text_secondary 167 196 183) */
    .phone{ width:280px; margin:0 auto; background:#0d2a1e; border-radius:34px; padding:16px 12px 22px;
      border:1px solid #1d4636; box-shadow:0 20px 40px rgba(0,0,0,.25); font-family:"Raleway",sans-serif; }
    .phone .bar{ display:flex; justify-content:space-between; font-size:.68em; color:#a7c4b7; padding:2px 10px 14px; }
    .notif{ background:#123627; border-radius:16px; padding:12px 14px; color:#f5f4f0; }
    .notif .app{ font-size:.66em; letter-spacing:.08em; color:#a7c4b7; display:flex; justify-content:space-between; }
    .notif .t{ font-weight:700; font-size:.95em; margin-top:6px; }
    .notif .d{ font-size:.8em; color:#a7c4b7; margin-top:4px; line-height:1.45; }
    .appcard{ background:#123627; border-radius:16px; padding:14px; color:#f5f4f0; margin-top:10px; }
    .appcard .k{ font-size:.64em; letter-spacing:.12em; text-transform:uppercase; color:#34d399; }
    .appcard .big{ font-size:1.5em; font-weight:700; margin:4px 0 2px; }
    .appcard .row{ display:flex; justify-content:space-between; font-size:.78em; color:#a7c4b7;
      padding:5px 0; border-top:1px solid #1d4636; }
    .appcard .row b{ color:#f5f4f0; font-weight:600; font-variant-numeric:tabular-nums; }
    .appcard .disc{ width:54px; height:54px; border-radius:50%; background:#e2ded2; margin:8px auto 10px;
      position:relative; overflow:hidden; }
    .appcard .disc::after{ content:""; position:absolute; inset:0; border-radius:50%;
      background:#0d2a1e; transform:translateX(-4px); }
    .phone .home{ width:110px; height:4px; background:#1d4636; border-radius:2px; margin:18px auto 0; }

    /* ---- the spread: the objects, arranged, on the sky ---- */
    .spread{ position:relative; overflow:hidden; background:#05070d; margin:0; padding:24px 6% 64px; }
    .spread .bg{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; opacity:.55; }
    .spread::after{ content:""; position:absolute; inset:0; pointer-events:none;
      background:linear-gradient(to top,rgba(5,7,13,.85) 0%,rgba(5,7,13,.25) 50%,rgba(5,7,13,.6) 100%); }
    .spread .tiles{ position:relative; z-index:2; max-width:1180px; margin:0 auto; display:grid;
      grid-template-columns:repeat(12,1fr); grid-auto-rows:64px; gap:16px; }
    .spread .tile{ margin:0; border-radius:14px; overflow:hidden; border:1px solid rgba(245,244,240,.16);
      background:#f5f4f0; box-shadow:0 24px 50px rgba(0,0,0,.45); }
    .spread .tile img{ width:100%; height:100%; object-fit:cover; object-position:top; display:block; }
    .spread .t-phone,.spread .t-notif{ background:transparent; border:none; box-shadow:none; }
    .t-phone{ grid-column:1/span 3; grid-row:1/span 7; background:transparent; border:none; box-shadow:none; display:flex; align-items:center; }
    .t-phone .phone{ width:100%; max-width:250px; }
    .t-plate{ grid-column:4/span 3; grid-row:1/span 6; }
    .t-book{ grid-column:7/span 3; grid-row:2/span 5; }
    .t-map{ grid-column:10/span 3; grid-row:1/span 3; background:#05070d; }
    .t-cover{ grid-column:10/span 3; grid-row:4/span 4; background:#000; }
    .t-sky{ grid-column:4/span 3; grid-row:7/span 3; background:#05070d; }
    .t-notif{ grid-column:7/span 3; grid-row:7/span 2; background:transparent; border:none; box-shadow:none; display:flex; align-items:center; }
    .t-notif .notif{ width:100%; box-shadow:0 18px 40px rgba(0,0,0,.45); }
    .t-analemma{ grid-column:1/span 3; grid-row:8/span 2; }
    .spread .shot-note{ position:absolute; right:6%; bottom:16px; z-index:2; font-family:"Open Sans",sans-serif;
      font-size:.64em; letter-spacing:.13em; text-transform:uppercase; color:rgba(245,244,240,.5); }
    @media (max-width:980px){
      .spread{ padding:28px 5% 44px; }
      .spread .tiles{ grid-template-columns:repeat(6,1fr); grid-auto-rows:56px; gap:12px; }
      .spread .t-phone,.spread .t-notif{ background:transparent; border:none; box-shadow:none; }
    .t-phone{ grid-column:1/span 3; grid-row:1/span 7; }
      .t-plate{ grid-column:4/span 3; grid-row:1/span 5; }
      .t-cover{ grid-column:4/span 3; grid-row:6/span 3; }
      .t-book{ grid-column:1/span 3; grid-row:8/span 4; }
      .t-map{ grid-column:4/span 3; grid-row:9/span 2; }
      .t-notif{ grid-column:4/span 3; grid-row:11/span 2; }
      .t-sky,.t-analemma{ display:none; }
    }
    .forms-line{ position:relative; z-index:2; text-align:center; color:#c9d4d8; font-family:"Open Sans",sans-serif;
      font-size:.82em; letter-spacing:.08em; text-transform:uppercase; margin:34px auto 0; max-width:900px; line-height:2; }
    .forms-line b{ color:#fff; font-weight:600; }
    .mo.dark.subject h2{ font-size:clamp(2.6em,6vw,5em); }
    .mo.dark.subject .k{ font-size:.8em; }
    .mo .facts{ position:relative; z-index:2; display:flex; gap:28px; justify-content:center; flex-wrap:wrap; margin-top:26px;
      font-family:"Open Sans",sans-serif; font-size:.78em; letter-spacing:.06em; text-transform:uppercase; color:#a7c4b7; }
    /* ---- subjects: abstraction first, then the image ---- */
    .sub{ padding:88px 6%; }
    .sub .wrap{ max-width:1180px; margin:0 auto; display:grid; grid-template-columns:1fr 1.15fr; gap:56px; align-items:center; }
    .sub .k{ font-family:"Open Sans",sans-serif; font-size:.74em; font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:var(--accent); margin-bottom:14px; }
    .sub h2{ font-size:clamp(2.4em,5vw,4.4em); line-height:1.02; margin:0 0 18px; color:var(--ink); }
    .sub p{ font-size:1.15em; line-height:1.55; color:var(--muted); margin:0; max-width:40ch; }
    .sub .facts{ display:flex; gap:10px 22px; flex-wrap:wrap; margin-top:22px; font-family:"Open Sans",sans-serif; font-size:.74em; letter-spacing:.06em; text-transform:uppercase; color:var(--muted2); }
    .sub .go{ display:inline-block; margin-top:22px; font-weight:600; color:var(--accent); text-decoration:none; border-bottom:1.5px solid currentColor; padding-bottom:2px; }
    .sub .fig{ width:100%; }
    .sub .fig svg{ width:100%; height:auto; display:block; }
    /* A caption for a figure that lives INSIDE a section rather than in a
       full-bleed band. Bands have `.cap` — 10px uppercase, absolutely
       positioned over the image. That is a label, not a sentence, and it cannot
       be used here because it is positioned against the band. This is the
       sentence: normal case, normal size, in the flow under the drawing, so a
       figure can say what it shows without costing a band of its own. */
    .sub .fig .figcap{ margin-top:12px; font-size:.82em; color:var(--muted);
      line-height:1.6; max-width:52ch; }
    .sub .fig2{ display:grid; grid-template-columns:1fr 1fr; gap:24px; align-items:center; }
    .sub.paper{ background:var(--bg); }
    .sub.emerald{ background:#0d2a1e; --ink:#f5f4f0; --muted:#a7c4b7; --muted2:#7fa08f; --hair:rgba(255,255,255,.14); --accent:#34d399; }
    .sub.ink{ background:#0b1210; --ink:#f5f4f0; --muted:#b8c9c0; --muted2:#7d8f86; --hair:rgba(255,255,255,.12); --accent:#34d399; }
    .sub.rev .wrap{ grid-template-columns:1.15fr 1fr; }
    .sub.rev .wrap .fig{ order:-1; }
    /* Was clamp(320px,52vh,560px) — over half the viewport for one photograph,
       so every band cost a whole screen of scroll. That was cut to
       clamp(180px,26vh,300px), and the cut overshot for a reason worth writing
       down: the middle term was tied to viewport HEIGHT. On an ordinary laptop
       the content viewport is ~690px tall, 26vh is 179px, and the clamp
       therefore pinned to its 180px FLOOR on every desktop — the preferred value
       never once applied. So a 2880px-wide rendered map and an 1800px star field
       were both shown as 180px letterbox slots while the drawn charts either
       side of them took 500-680px each. The photograph, the expensive thing, was
       the smallest element on the page.

       Height now tracks viewport WIDTH, which is what a full-bleed strip
       actually spans: at 1351px wide a band is 297px, at 1600px it is 352px,
       and it stops at 380px however wide the screen. Still punctuation between
       two sections rather than a destination — 297px is 43% of that laptop
       viewport, not 100% — but the image is now legible as an image. */
    .band-img{ position:relative; height:clamp(230px,22vw,380px); overflow:hidden; background:#05070d; }
    /* There WAS a `.band-img.flat` here that held two bands down at 191px,
       justified by a detail score: mean absolute difference between a pixel
       and the one BESIDE it, measured on the green channel. That metric only
       looks along the horizontal axis, so a smooth vertical gradient scores
       near zero however much light it actually carries. Measuring both axes,
       and also the top-to-bottom tonal swing, tells a different story:

                              horiz   vert   luminance   warmth
                                                 range    range
           sky-dawn.jpg        0.11   0.53          51      194
           band-ridge.jpg      0.78   0.93          62       21
           band-meteor.jpg     0.80   0.90           8        8
           band-world-green   16.56  21.38          18        8
           band-stars.jpg      8.37   8.33           8        3
           band-galaxy.jpg     8.58   8.45           6        5

       sky-dawn has the largest tonal range on the site — 194 points of red
       minus blue from the top of the frame to the bottom. It is not an empty
       image, it is a gradient image, and the gradient IS the content.
       band-ridge is not a gradient at all: it is a moonrise over a ridge, a
       drawing with a subject, and 62 points of luminance range. Neither
       belonged in a class called flat. Both are back at the full height.

       Keep the lesson, not the class: before shrinking a band because its
       picture looks empty, check which axis carries it. */

    /* ---- NO BAND MAY ENLARGE ITS PICTURE ---------------------------------
       object-fit:cover on a full-bleed band does two things at once, and the
       second one is not obvious: it takes a horizontal slice of the file AND
       it scales that slice up to the width of the window. The scale is
       window width / file width, so it grows with the monitor. Measured:

                              1366   1600   1920   2560
           sky-dawn.jpg      x1.06  x1.24  x1.49  x1.99
           band-ridge.jpg    x0.84  x0.99  x1.19  x1.59
           band-stars.jpg    x0.75  x0.88  x1.06  x1.41
           band-galaxy.jpg   x0.75  x0.88  x1.06  x1.41
           hero-night.jpg    x0.70  x0.83  x0.99  x1.33
           band-world-green  x0.47  x0.56  x0.66  x0.88

       Six of these are enlarged on a 1920 monitor and eight on a 2560. On a
       2560 screen the dawn band was showing 24% of its file blown up to
       twice size — a zoom into a small part, which is exactly the way to make
       a good picture look cheap.

       Note that pre-cropping the file does NOT fix this on its own: for a
       full-bleed band the scale is set by the window, so a cropped file lands
       at the identical factor. The crop decides WHICH pixels; only a width
       cap decides whether they are enlarged. So both, together:

         1. the file is cropped to the slice we actually want to show, at
            native resolution, so CSS is not choosing the composition; and
         2. the band stops growing at the file's own width.

       Past that width the band centres on the page instead of enlarging.
       That is the honest trade: a margin on a very wide monitor, in exchange
       for a picture that is sharp on every monitor.
       The world map (.band-img.whole) is deliberately NOT one of these: it runs
       full screen at any width, by instruction. See the note there. */
    .band-img.exact{ height:auto; overflow:visible;
      max-width:var(--nat); margin-left:auto; margin-right:auto; }
    .band-img.exact img{ width:100%; height:auto; object-fit:fill; }

    /* sky-dawn is the exception, and it is allowed to run full-bleed at any
       width without losing anything, because it holds NO horizontal
       information: measured across the row, mean neighbour difference is
       0.11 — the rows are uniform. Stretching a uniform row is exact. So the
       height is pinned to the cropped file's own height (320px, so every row
       maps 1:1 and nothing is resampled vertically) and the width is left to
       stretch. No cap, no bars, and no zoom either.

       The file it points at is sky-dawn-band.jpg: rows 480-800 of the
       original, cropped at native resolution. The dawn light lives in the
       bottom third of that frame (warmth runs -19 at the middle of the file
       to +153 at the last row) and the old centre crop was showing rows
       39%-61% — the one strip with no sunlight anywhere in it, under a
       caption promising light. */
    .band-img.horizon{ height:320px; }
    .band-img.horizon img{ object-fit:fill; }
    /* The ::after exists to darken the bottom edge so an overlaid caption
       stays legible. Here the bottom edge IS the sunlight, and darkening it
       by 60% black undoes the fix above. Drop the veil and put the caption
       in ink instead — dark type on gold reads better than pale type on a
       gold that has been muddied to make pale type work. */
    .band-img.horizon::after{ display:none; }
    .band-img.horizon .cap{ color:rgba(18,22,16,.74); }
    .band-img img{ width:100%; height:100%; object-fit:cover; display:block; }
    .band-img::after{ content:""; position:absolute; inset:0; background:linear-gradient(to top,rgba(5,7,13,.6) 0%,rgba(5,7,13,0) 38%); pointer-events:none; }
    .band-img .cap{ z-index:2; }
    .band-img .cap{ position:absolute; left:6%; bottom:22px; font-family:"Open Sans",sans-serif; font-size:.66em; letter-spacing:.14em; text-transform:uppercase; color:rgba(245,244,240,.65); }
    /* A band that shows a plate WHOLE.
       .band-img above crops to a clamped height with object-fit:cover. That is
       right for a photograph — you lose the edges and nobody minds. It is wrong
       for a map: cover at band height slices the top and bottom off a 2:1
       equirectangular plate, and on the world relief those are the Arctic and
       the Antarctic ice sheets, which are the part worth showing. This variant
       keeps the plate's own aspect ratio and lets the band take the height that
       needs. The ::after gradient and the .cap are both positioned against the
       band, so both still work once the band is auto-height. */
    .band-img.whole{ height:auto; padding:0; }
    /* FULL SCREEN. Edge to edge, no cap, no padding, no letterbox.
       There was an 820px max-width here with a comment arguing that a 2:1 plate
       run edge to edge is "a whole screen for one picture" and that the detail
       is no more legible at that size. Erick has asked for this map full screen
       more times than that argument is worth. It is the world, drawn from one
       elevation field pole to pole, and it is the reason the earth page exists;
       it gets the screen. Do not cap it again.
       width:100% with height:auto and no object-fit: the file is 2000x1000, an
       exact 2:1, so the box always matches the plate's own ratio and nothing is
       ever cropped or squashed at any width.

       max-width is the file's OWN width, 2000px. Full screen on every normal
       monitor, and it stops there — the map is never blown up past 1:1. The
       number is the render's width and nothing else; if a wider plate is ever
       rendered, change this to match it. Do not put an arbitrary cap back. */
    .band-img.whole img{ width:100%; height:auto; max-width:2000px; margin:0 auto; }
    /* The caption stays in flow under the plate rather than overlaid on it. The
       bottom edge of this map is the Antarctic ice sheet — near-white — and the
       .cap type is light, so an overlaid caption disappears into the ice. */
    .band-img.whole .cap{ position:static; max-width:none; margin:14px auto 18px;
      padding:0; text-align:center; }
    /* The bottom gradient exists to keep an overlaid caption legible. There is
       no longer an overlaid caption here, and over a letterboxed plate it just
       darkens the ocean along the bottom edge. */
    .band-img.whole::after{ display:none; }
    /* A band that is only a band: full-bleed, edge to edge, no caption on it and
       nothing to read. The ::after gradient exists to keep overlaid caption type
       legible against a picture; with no caption it is just an unexplained
       darkening along the bottom edge, so it goes. Everything else — the cover
       crop, the clamped height — is the default .band-img, which is what makes
       it cover the full width whatever the window is doing. */
    .band-img.plain::after{ display:none; }
    /* Give the real picture the room. The default .band-img height tops out at
       300px, which on a normal window rendered this map as a 180px strip —
       while the decorative charts either side of it took 632px each. That is
       backwards: the strip is a genuine 2880px render of the world, and it was
       the smallest thing on the page.

       25vw rather than a vh clamp because the image is 4:1 and spans the full
       width: at any window width, 25vw is almost exactly the height the image
       wants, so it shows whole instead of being cropped to a letterbox. The
       260px floor keeps it from collapsing to a hairline on a phone, where
       object-fit:cover then crops to the middle of the drawing. */
    .band-img.plain{ height:clamp(260px,25vw,440px); }
    @media (max-width:980px){ .sub .wrap,.sub.rev .wrap{ grid-template-columns:1fr; gap:30px; } .sub.rev .wrap .fig{ order:0; } .sub{ padding:60px 6%; } }

    /* ---- a shelf of real artefacts --------------------------------------
       These were written for the home page and lived in ca-work.css, which
       only the home page and the organisations page load. The subject pages
       show the same objects — rendered plates, relief crops, planet renders —
       so the rules belong here, where all six pages can reach them. Anything
       here is deliberately NOT repeated in ca-work.css; that file loads after
       this one and a second copy would be a competing definition. */
    .gallery{ display:grid; grid-template-columns:repeat(4,1fr); gap:16px; }
    .gallery figure{ margin:0; }
    .gallery img{ width:100%; aspect-ratio:3/4; object-fit:cover; object-position:top;
      border-radius:12px; border:1px solid var(--nav-border); background:#fff; }
    /* .sq is for renders rather than pages: a render has no top edge to hold to. */
    .gallery.sq img{ aspect-ratio:1/1; object-position:center; background:#05070d; }
    .gallery figcaption{ font-size:.82em; color:var(--muted); margin-top:8px; line-height:1.5; }
    .gallery figcaption b{ display:block; color:var(--ink); font-weight:600; }
    /* .tall is for the vector map plates, which are rendered 1100x1270 — taller
       than they are wide, the proportion of a sheet on a wall. Forcing them into
       the 3/4 page ratio above cropped the top and bottom off every one. */
    .gallery.tall img{ aspect-ratio:11/13; object-position:center; background:#05070d; }
    /* .relief holds the hypsometric crops. They are square-ish cuts from the
       world plate, and unlike the printed pages they have no top edge to align
       to — the subject is in the middle of the frame. */
    .gallery.relief img{ aspect-ratio:1/1; object-position:center; background:#0d2035; }
    .gallery.three{ grid-template-columns:repeat(3,1fr); }
    /* .gallery.three has to be named here too. It is the more specific selector,
       so a bare `.gallery{...}` in this query does not override it and the
       three-column galleries stayed three-column on a phone — 96px planets. */
    @media (max-width:980px){ .gallery,.gallery.three{ grid-template-columns:1fr 1fr; } }
    /* One across below 560px. Two columns of a 380px phone leaves ~170px, which
       is under the width at which a hairline coastline or a lit terminator is
       worth showing at all. These are the pictures; give them the screen. */
    @media (max-width:560px){ .gallery,.gallery.three{ grid-template-columns:1fr; } }
    .band-svg{ position:relative; padding:56px 6%; display:grid; place-items:center; overflow:hidden; }
    .band-svg.ink{ background:#0b1210; --ink:#f5f4f0; --muted:#b8c9c0; --muted2:#7d8f86; --hair:rgba(255,255,255,.12); --accent:#34d399; }
    .band-svg .ring{ width:min(520px,80vw); }
    .band-svg .ring svg{ width:100%; height:auto; display:block; }
    .band-svg .cap{ position:absolute; left:6%; bottom:22px; font-family:"Open Sans",sans-serif; font-size:.66em; letter-spacing:.14em; text-transform:uppercase; color:rgba(245,244,240,.5); }
    /* ---- the verbs ---- */
    .verbs{ background:var(--bg); padding:88px 6% 72px; }
    .vwrap{ max-width:1180px; margin:0 auto; text-align:center; }
    .verbs .k{ font-family:"Open Sans",sans-serif; font-size:.74em; font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:var(--accent); margin-bottom:14px; }
    .verbs h2{ font-size:clamp(2.2em,4.6vw,3.8em); margin:0 0 10px; }
    .verbs .lede{ margin:0 auto 40px; }
    .vgrid{ display:grid; grid-template-columns:repeat(6,1fr); gap:18px; text-align:left; }
    .v{ text-decoration:none; color:inherit; display:block; }
    .v .pic{ aspect-ratio:4/5; border-radius:14px; overflow:hidden; border:1px solid var(--nav-border); background:#0d2a1e; display:grid; place-items:center; padding:0; }
    .v .pic.paper{ background:#fff; }
    .v .pic img{ width:100%; height:100%; object-fit:cover; object-position:top; display:block; }
    .v .pic.mock{ padding:14px; }
    .v .notif{ background:#123627; border-radius:14px; padding:12px; color:#f5f4f0; width:100%; font-family:"Raleway",sans-serif; }
    .v .notif .app{ font-size:.6em; letter-spacing:.08em; color:#a7c4b7; display:flex; justify-content:space-between; }
    .v .notif .t{ font-weight:700; font-size:.88em; margin-top:6px; }
    .v .notif .d{ font-size:.72em; color:#a7c4b7; margin-top:3px; }
    .v .mini-phone{ width:100%; background:#123627; border-radius:16px; padding:12px; color:#f5f4f0; font-family:"Raleway",sans-serif; }
    .v .mini-phone .mk{ font-size:.58em; letter-spacing:.12em; text-transform:uppercase; color:#34d399; }
    .v .mini-phone .mb{ font-weight:700; font-size:1em; margin:4px 0 6px; }
    .v .mini-phone .mr{ display:flex; justify-content:space-between; font-size:.68em; color:#a7c4b7; padding:4px 0; border-top:1px solid #1d4636; }
    .v .mini-phone .mr b{ color:#f5f4f0; font-weight:600; display:inline; margin:0; font-size:1em; }
    .v .imprint{ position:relative; width:100%; height:100%; }
    .v .imprint .masthead{ position:absolute; left:0; right:0; top:0; background:#f5f4f0; border-bottom:2px solid #272424; padding:8px 10px; font-family:"Raleway",sans-serif; }
    .v .imprint .masthead b{ font-size:.8em; letter-spacing:.06em; color:#272424; display:inline; margin:0; }
    .v .imprint img{ padding-top:36px; object-fit:cover; object-position:left top; }
    .v b{ display:block; margin-top:12px; font-size:1.05em; }
    .v span{ display:block; font-size:.82em; color:var(--muted); line-height:1.5; }
    /* ---- quiet build ---- */
    .quiet{ background:var(--bg); padding:64px 6% 72px; border-top:1px solid var(--hair); }
    .qwrap{ max-width:720px; margin:0 auto; text-align:center; }
    .quiet .k{ font-family:"Open Sans",sans-serif; font-size:.7em; font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:var(--muted2); margin-bottom:12px; }
    .quiet p{ font-size:1.02em; line-height:1.7; color:var(--muted); margin:0; }
    .quiet a{ color:var(--accent); font-weight:600; text-decoration:underline; text-underline-offset:3px; }
    @media (max-width:980px){ .vgrid{ grid-template-columns:repeat(3,1fr); } }
    @media (max-width:560px){ .vgrid{ grid-template-columns:1fr 1fr; } }
    /* ---- moments: one instance per screen, Apple-style ---- */
    /* Was 88vh, with .mo.top at 92vh below. "One instance per screen" is the
       right idea for a product launch page with six things to say; this site has
       thirty objects to show and a full-bleed screen-and-a-bit of photograph
       before the first of them is a cost, not a statement. 58vh still fills the
       eye and still leaves the top of the next section visible, which is what
       actually makes a reader keep going. */
    .mo{ position:relative; overflow:hidden; display:grid; place-items:center; text-align:center;
      min-height:58vh; padding:64px 6%; margin:0; }
    .mo .bg{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; z-index:0; }
    .mo .in{ position:relative; z-index:2; max-width:920px; }
    .mo .k{ font-family:"Open Sans",sans-serif; font-size:.74em; font-weight:700; letter-spacing:.16em; text-transform:uppercase; margin-bottom:16px; }
    .mo h2{ font-size:clamp(2.2em,5.2vw,4.2em); line-height:1.04; letter-spacing:-.01em; margin:0 0 18px; }
    .mo p{ font-size:clamp(1.05em,1.6vw,1.35em); line-height:1.5; margin:0 auto; max-width:40ch; }
    .mo .links{ margin-top:22px; display:flex; gap:26px; justify-content:center; flex-wrap:wrap; }
    .mo .links a{ font-weight:600; font-size:1.02em; text-decoration:none; border-bottom:1.5px solid currentColor; padding-bottom:2px; }
    .mo .obj{ position:relative; z-index:2; margin-top:40px; max-width:min(620px,84vw); box-shadow:0 40px 90px rgba(0,0,0,.28); border-radius:14px; overflow:hidden; }
    .mo .obj img{ width:100%; display:block; }
    .mo.dark{ background:#05070d; color:#f5f4f0; }
    .mo.dark .k{ color:#34d399; } .mo.dark p{ color:#c9d4d8; } .mo.dark .links a{ color:#fff; }
    .mo.dark{ align-items:start; }
    .mo.dark .bg{ object-position:center 72%; }
    .mo.dark::after{ content:""; position:absolute; inset:0; z-index:1; background:linear-gradient(to bottom,rgba(5,7,13,.86) 0%,rgba(5,7,13,.55) 32%,rgba(5,7,13,0) 62%); }
    .mo.dark.top::after{ background:linear-gradient(to bottom,rgba(5,7,13,.72) 0%,rgba(5,7,13,.15) 45%,rgba(5,7,13,.2) 100%); }
    .mo.paper{ background:var(--bg); color:var(--ink); }
    .mo.paper .k{ color:var(--accent); } .mo.paper p{ color:var(--muted); } .mo.paper .links a{ color:var(--accent); }
    .mo.emerald{ background:#0d2a1e; color:#f5f4f0; }
    .mo.dark h2,.mo.emerald h2,.mo.dark h1{ color:#fff; }
    .mo.emerald .k{ color:#34d399; } .mo.emerald p{ color:#a7c4b7; } .mo.emerald .links a{ color:#fff; }
    .mo.emerald .phone{ margin-top:44px; width:300px; }
    .mo.top{ min-height:64vh; align-items:center; }
    .mo.top .bg{ object-position:center; }
    .mo.top h1{ font-size:clamp(2.6em,6.4vw,5.2em); line-height:1.02; margin:0 0 20px; color:#fff; }
    .mo.top .in{ margin-top:8vh; }
    .pair{ display:grid; grid-template-columns:1fr 1fr; gap:14px; padding:14px 14px; background:var(--bg); }
    .pair .mo{ min-height:72vh; border-radius:22px; padding:52px 8%; }
    .pair .mo h2{ font-size:clamp(1.8em,3.2vw,2.6em); }
    .free-lead{ text-align:center; padding:72px 6% 0; }
    .free-lead h2{ font-size:clamp(2em,4.4vw,3.4em); margin:0 0 10px; }
    .free-lead p{ color:var(--muted); font-size:1.15em; margin:0 auto; max-width:44ch; }
    .build{ text-align:center; align-items:center !important; }
    .build::after{ background:rgba(5,7,13,.72) !important; }
    .build .lanes{ display:grid; grid-template-columns:repeat(3,1fr); gap:14px; margin:40px auto 0; max-width:1100px; text-align:left; }
    .build .lane{ background:rgba(255,255,255,.05); border:1px solid rgba(255,255,255,.1); border-radius:16px; padding:24px; }
    .build .lane h3{ font-size:1.15em; margin:0 0 8px; }
    .build .lane p{ font-size:.92em; color:#b8c9c0; line-height:1.65; margin:0 0 10px; max-width:none; }
    .build .lane a{ color:var(--accent-light); font-weight:600; text-decoration:underline; text-underline-offset:3px; font-size:.9em; }
    @media (max-width:900px){ .pair{ grid-template-columns:1fr; } .build .lanes{ grid-template-columns:1fr; } .mo{ min-height:52vh; } .pair .mo{ min-height:60vh; } }
  
/* ---- subject pages ---- */
.sub .h1{ font-size:clamp(2.8em,6vw,5.4em); line-height:1; margin:0 0 18px; color:var(--ink); }
.measures{ list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(4,1fr); gap:0 28px; border-top:1px solid var(--hair); }
.measures li{ text-indent:0; margin:0; padding:12px 0; border-bottom:1px solid var(--hair); font-size:.9em; line-height:1.5; }
.measures li b{ display:block; color:var(--ink); font-weight:700; }
.measures li span{ color:var(--muted); }
.band-svg .wide{ width:min(1180px,100%); }
.band-svg .wide svg{ width:100%; height:auto; display:block; }
.band-svg.paper{ background:var(--bg); }

/* ─── A graphic has to earn its height ──────────────────────────────────────
   Plain `.band-svg` is a full-bleed slab with one drawing centred in it and a
   caption line along the bottom. Measured on the home page that came to 632px
   of screen carrying 19 words; on earth.html, 794px carrying 36. The drawings
   are good, but a reader who does not already know how to read a radial hour
   chart gets nothing from one, and a caption in 10px uppercase is not a
   substitute for saying what the thing shows.

   `read` puts the drawing and a short read side by side: a heading, a line of
   what it is, and bullets for how to read it — what the axis is, what the
   rings mean, what a shape is telling you. The height then buys information
   instead of margin. It also CAPS the drawing at 400px: alone and centred it
   grew to 520px and owned the whole viewport, which is what made these bands
   feel like interruptions rather than parts of the argument.

   The caption element is not used inside a read band — its text becomes the
   heading, where it can be read at a normal size. */
.band-svg.read{ display:block; padding:48px 6%; }
.band-svg.read .in{ max-width:1120px; margin:0 auto; display:grid;
  grid-template-columns:minmax(240px,400px) 1fr; gap:clamp(28px,4vw,64px);
  align-items:center; }
.band-svg.read .ring{ width:100%; max-width:400px; }
.band-svg.read .wide{ width:100%; }
/* Landscape plates need the opposite split. The column above is sized for a
   square ring: cap it at 400px and the text gets the rest. A 900x300 or 900x420
   chart squeezed into 400px is 133px tall and its 10px axis labels are
   unreadable, so `fig-wide` gives the drawing the larger share and lets the
   read run narrower beside it. At 1120px that is roughly 640px of chart against
   400px of text — the chart keeps a legible scale and the band still costs
   about half of what the centred slab did. */
.band-svg.read.fig-wide .in{ grid-template-columns:1.6fr minmax(280px,1fr); }
.band-svg.read.fig-wide .wide{ max-width:none; }
.band-read h3{ font-family:"Raleway",sans-serif; font-weight:700; line-height:1.15;
  font-size:clamp(1.3em,2.6vw,1.9em); margin:0 0 12px; color:var(--ink); }
.band-read p{ margin:0 0 16px; color:var(--muted); max-width:54ch; line-height:1.6; }
.band-read ul{ margin:0; padding:0; list-style:none; }
/* text-indent:0 is required, not tidiness. ca-site.css sets a site-wide
   `li{ text-indent:-.7em; padding-left:.7em }` hanging indent for prose lists;
   left in place it pulled the first line of every bullet 11px to the LEFT of
   its own wrapped lines, so the bold lead-in sat proud of the paragraph. Every
   other list component here resets it the same way (.layers, .measures,
   .applist) — this one has to as well. */
.band-read li{ position:relative; text-indent:0; padding-left:26px; margin:0 0 10px;
  color:var(--muted); max-width:54ch; line-height:1.55; font-size:.95em; }
/* A short accent rule instead of a bullet glyph: the dot sat on the text
   baseline and read as a full stop at the start of every line. */
.band-read li::before{ content:""; position:absolute; left:0; top:.66em;
  width:9px; height:1px; background:var(--accent); }
.band-read li b{ color:var(--ink); font-weight:600; }
/* Stack below 820px. The drawing goes FIRST and shrinks — on a phone the text
   is the reason to keep scrolling, and a 400px ring above it is a wall. */
@media (max-width:820px){
  .band-svg.read{ padding:38px 6%; }
  .band-svg.read .in,
  .band-svg.read.fig-wide .in{ grid-template-columns:1fr; gap:24px; }
  .band-svg.read .ring{ max-width:300px; margin:0 auto; }
}
.applist{ list-style:none; padding:0; margin:0; }
.applist li{ text-indent:0; padding:12px 0; margin:0; border-bottom:1px solid var(--hair); font-size:.92em; color:var(--muted); line-height:1.5; }
.applist li b{ color:var(--ink); font-weight:700; display:block; }
.applist li.house{ border-bottom:2px solid var(--accent); }
.rest{ background:var(--bg); padding:56px 6%; border-top:1px solid var(--hair); }
.rwrap{ max-width:1180px; margin:0 auto; }
.rest .k{ font-family:"Open Sans",sans-serif; font-size:.7em; font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:var(--muted2); margin-bottom:18px; }
.rgrid{ display:grid; grid-template-columns:repeat(3,1fr); gap:18px; }
.rgrid a{ text-decoration:none; color:inherit; display:block; padding:20px 22px; border:1px solid var(--nav-border); border-radius:14px; background:var(--card); }
.rgrid .ek{ display:block; font-family:"Open Sans",sans-serif; font-size:.66em; letter-spacing:.14em; text-transform:uppercase; color:var(--accent); }
.rgrid b{ display:block; font-size:1.2em; margin:6px 0 4px; }
.rgrid span{ display:block; font-size:.86em; color:var(--muted); }
.sub .fig.fig2 svg{ width:100%; }
@media (max-width:980px){ .measures{ grid-template-columns:1fr 1fr; } .rgrid{ grid-template-columns:1fr; } }

.appgrid{ display:grid; grid-template-columns:repeat(4,1fr); gap:16px; }
.appcardx{ border:1px solid rgba(255,255,255,.12); border-radius:14px; padding:20px; background:rgba(255,255,255,.04); }
.appcardx.house{ grid-column:1/-1; border-color:var(--accent); }
.appcardx .ek{ font-family:"Open Sans",sans-serif; font-size:.64em; letter-spacing:.14em; text-transform:uppercase; color:var(--accent); }
.appcardx h3{ font-size:1.3em; margin:6px 0 8px; color:var(--ink); }
.appcardx p{ font-size:.9em; color:var(--muted); line-height:1.6; margin:0; max-width:none; }
@media (max-width:980px){ .appgrid{ grid-template-columns:1fr 1fr; } }

/* ---- the apps, one row each -------------------------------------------
   This replaced a grid of eight cards. Cards force every app into the same
   small box, which flattens the difference between the house app that holds
   the whole arc and a small one that does a single job — and a box that size
   only has room for a slogan, so none of them was actually described.
   A row per app instead: the drawing on one side, and on the other the
   name, the one line that says what it IS, and a paragraph that says what
   it does for you. Rows alternate side so the eye keeps moving down the
   page rather than scanning a grid.
   The drawings are the site's own diagrams of the quantity each app
   computes — the 29.53-day phase ring for Moon, the twilight bands for
   Wake, the uncertainty band for Flow. They are not screenshots, because
   there is nothing to screenshot yet, and a mocked-up screen would be a
   picture of a product that does not exist.                             */
.appline{ display:grid; grid-template-columns:300px 1fr; gap:38px; align-items:center;
  padding:34px 0; border-top:1px solid var(--hair); }
/* The rows are wrapped in .applines and counted with :nth-child, not
   :nth-of-type. :nth-of-type counts every sibling <div> regardless of class,
   so the section's own intro div (heading + lede) was row 1 and the house app
   came out "even" — it rendered mirrored, with a rule above it. A wrapper
   that holds nothing but the rows makes the count mean what it reads as. */
.applines .appline:first-child{ border-top:none; }
/* Even rows put the drawing on the right. `direction` would flip the text
   too, so the columns are reordered explicitly instead. */
.applines .appline:nth-child(even) .appline-art{ order:2; }
.applines .appline:nth-child(even){ grid-template-columns:1fr 300px; }
.appline-art{ margin:0; }
.appline-art img{ width:100%; height:170px; object-fit:contain; display:block; }
.appline-art figcaption{ margin-top:10px; font-size:.74em; line-height:1.45;
  color:var(--muted2); text-align:center; }
.appline .ek{ font-family:"Open Sans",sans-serif; font-size:.66em; font-weight:700;
  letter-spacing:.15em; text-transform:uppercase; color:var(--accent); }
.appline h3{ font-size:1.65em; margin:8px 0 6px; color:var(--ink); line-height:1.1; }
.appline .one{ font-size:1.02em; color:var(--ink); margin:0 0 10px; font-weight:600; }
.appline p{ font-size:.95em; color:var(--muted); line-height:1.65; margin:0; max-width:62ch; }
/* The house app is the one that is not like the others, so it says so with
   a rule down its left edge rather than with a bigger box. */
.appline.house{ border-left:2px solid var(--accent); padding-left:28px; }
.appline.house h3{ font-size:2em; }

/* Every app is unreleased. Saying so once at the top is not enough — a
   reader who lands mid-page needs it on the row they are reading — but a
   loud badge eight times would drown the descriptions, so it is a quiet
   monospace tag that reads as a status, not as a sticker. */
.soon{ display:inline-block; margin-top:14px; font-family:"Open Sans",sans-serif;
  font-size:.66em; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:var(--muted2); border:1px solid var(--hair); border-radius:100px;
  padding:5px 12px; }

@media (max-width:860px){
  .appline,.applines .appline:nth-child(even){ grid-template-columns:1fr; gap:20px; }
  .applines .appline:nth-child(even) .appline-art{ order:0; }
  .appline-art img{ height:140px; }
  .appline.house{ padding-left:18px; }
}
