/* apple.css -- launch/apple: the facility's design system.

   The whole site re-skinned as a company's launch: dark by default (the
   product is a black box), light by the header's toggle. Loaded AFTER
   record.css (templates/base.html): record.css keeps the layout, the lightbox,
   the tables and every behaviour; this file is the look. Delete its <link>
   and the site is the terminal again.

   HOW THIS FILE IS BUILT -- so a change is made once, in one place:

     1  TOKENS      every value: colour, type, radius, surface, glow, motion,
                    control size. Change a token, the whole site follows.
     2  BASE        page, type, the terminal's marks switched off.
     3  BEHAVIOURS  each declared ONCE over one selector list:
                      LABEL    the mono, uppercase, tracked label
                      SURFACE  a rounded panel (radius on the box only)
                      FRAME    a rounded image (radius AND clip)
                      GROUP    children spaced apart, never on a grey backdrop
                      GLOW     the sun under the pointer
                      CONTROLS primary, secondary, icon, link; focus; states
     4  BARS        masthead, local nav, announcement, chips, footer
     5  SECTIONS    the home hero and close, page heroes, the statement
     6  COMPONENTS  what is particular to one component, and nothing more
     7  THEMES      light: token overrides, plus the dark bands
     8  MOTION      reduced motion

   A component never restates a behaviour: to round, label, space or light a
   new component, add its selector to the behaviour's list. If a value is
   needed twice, it is a token. */


/* ============================================================== 1 TOKENS */

@property --glow { syntax: "<number>"; inherits: false; initial-value: 0; }

:root {
  /* type: the sans speaks, the mono labels */
  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text", "Helvetica Neue",
          "Segoe UI", Helvetica, Arial, sans-serif;
  --code: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;
  --mono: var(--sans);              /* record.css's body face, now the sans */
  --t-body: 1.0625rem;              /* 17px */
  --t-data: 0.875rem;
  --t-micro: 0.75rem;
  --t-label: 0.7rem;
  --track-label: 0;
  --track-caps: 0.13em;             /* the label's tracking */

  /* ground and ink: black and bone */
  --ground:   #000000;
  --ground-2: #161617;              /* a surface on black */
  --ground-3: #1d1d1f;              /* a surface, hovered */
  --rule:     #424245;
  --rule-soft:#2a2a2c;
  --dim:      #86868b;
  --text:     #d2d2d7;
  --lum-max:  #f5f5f7;

  /* the marks' colours (merch/tee-cube-v1/spec.json) */
  --cyan:  #65c0cd;                 /* the cube's edge: links, focus */
  --sun-1: #fbd040;
  --sun-2: #f37267;
  --sun-3: #ed0498;
  --sunset: linear-gradient(90deg, var(--sun-1) 0%, var(--sun-2) 52%, var(--sun-3) 100%);
  --headline: var(--sunset);
  --link: var(--cyan);
  --focus: var(--cyan);
  --lamp: #3ddc84;
  /* record.css's accent, where it still reads */
  --amber: var(--sun-2); --amber-mid: #e0695f;
  --amber-low: rgba(243, 114, 103, 0.35); --amber-wash: rgba(243, 114, 103, 0.08);
  --new: #f5a623;

  /* shape */
  --radius-l: 28px;                 /* cards, panels with pictures */
  --radius-m: 18px;                 /* panels of text */
  --radius-s: 12px;                 /* small rows, chips */
  --pill: 980px;
  --gap: 1rem;                      /* between the members of a GROUP */

  /* surfaces */
  --surface: var(--ground-2);
  --surface-hover: var(--ground-3);
  --edge: rgba(255, 255, 255, 0.08);
  --glass: rgba(29, 29, 31, 0.72);
  --glass-edge: var(--edge);
  --lift: -4px;                     /* how far a card rises on hover */
  --lift-shadow: 0 18px 46px rgba(243, 114, 103, 0.14);

  /* the glow: one light, everywhere it appears */
  --glow-size: 380px;
  --glow-core: rgba(243, 114, 103, 0.15);    /* the sun, low */
  --glow-halo: rgba(251, 208, 64, 0.05);
  --glow-room: 4.5rem;              /* padding a scroll container keeps for it */

  /* motion: Halcyon's language (halcyondynamics.tech, src/scripts/site-motion.js)
     -- calm inevitability: small distances, a long ease-out, generous stagger,
     nothing springy, everything once. One curve, one rise, one pace. */
  --ease-calm: cubic-bezier(0.22, 1, 0.36, 1);
  --rise: 24px;                     /* how far a block travels as it arrives */
  --reveal-dur: 600ms;
  --stagger: 80ms;                  /* between siblings, capped at five steps */
  --img-dur: 700ms;                 /* an image fading in as it loads */
  --breathe: 1.03;                  /* a picture under the pointer */
  --breathe-dur: 700ms;

  /* controls */
  --ctl-h: 2.75rem;                 /* 44px: every tappable control */
  --ctl-h-s: 2rem;
  --btn-bg: #f5f5f7;   --btn-fg: #0a0a0b;   --btn-bg-hover: #ffffff;
  --btn-glow: 0 10px 34px rgba(243, 114, 103, 0.28), 0 0 0 1px rgba(255, 255, 255, 0.5);
  --btn2-edge: rgba(245, 245, 247, 0.30);    --btn2-hover: rgba(245, 245, 247, 0.08);
  --icon-bg: rgba(51, 51, 54, 0.72);         --icon-hover: rgba(80, 80, 84, 0.85);
  --press: 0.97;

  /* the haze: the sun's gradient as light at the top and the foot of every page */
  --haze: 0.26;                     /* its strength */
  --haze-top: 26rem;                /* how far down it reaches */
  --haze-bottom: 30rem;             /* how far up it reaches */
  --ambient: 1;                     /* the glow down the page body (0 = off) */
  --amb-tile: 150vh;                /* the glow repeats every screen and a half */
  --amb-w: 62%;                     /* how far in from the edge each glow reaches */

  /* bars */
  --bar-h: 3.1rem;                  /* the masthead's row: everything in it centres on this */
  --burger: 2.6rem;                 /* the menu button's box (a 41px tap target) */
  --burger-line: 1.15rem;           /* its three rules */
  --bar: rgba(22, 22, 23, 0.80);
  --bar-2: rgba(22, 22, 23, 0.72);
  --bar-edge: rgba(255, 255, 255, 0.08);
  --band: #0c0c0d;                  /* announcement */
  --dimword: #333336;               /* a statement word not yet lit */

  --shade: linear-gradient(180deg, rgba(0,0,0,0) 30%, rgba(0,0,0,0.7) 100%);

  /* cursors: record.css's shapes and hotspots, in the brand -- bone with an ink
     edge; the hand (interactive is a different SHAPE, not only a colour) tipped
     with the sun; the measuring cursors in the cube's cyan. Every element that
     names a cursor reads one of these, so this block is the only place to change them. */
  --cur-default: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='26'%3E%3Cpath d='M4 2v18l4.3-4.2 2.8 5.9 3-1.4-2.8-5.8H17z' fill='%230a0a0b' fill-opacity='.45' stroke='%230a0a0b' stroke-opacity='.45' stroke-width='3' stroke-linejoin='round'/%3E%3Cpath d='M4 2v18l4.3-4.2 2.8 5.9 3-1.4-2.8-5.8H17z' fill='%23f5f5f7' stroke='%230a0a0b' stroke-width='1' stroke-linejoin='round'/%3E%3C/svg%3E") 4 2, default;
  /* over anything you can press: the same arrow as at rest, filled with the
     sun's vaporwave gradient, an ink edge and a hard offset shadow like a 1990s
     system cursor (the artist: no finger, no stripes). */
  --cur-link: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='28' shape-rendering='crispEdges'%3E%3Cdefs%3E%3ClinearGradient id='sun' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%23fbd040'/%3E%3Cstop offset='.55' stop-color='%23f37267'/%3E%3Cstop offset='1' stop-color='%23ed0498'/%3E%3C/linearGradient%3E%3CclipPath id='hand'%3E%3Cpath d='M4 2v18l4.3-4.2 2.8 5.9 3-1.4-2.8-5.8H17z'/%3E%3C/clipPath%3E%3C/defs%3E%3Cpath d='M4 2v18l4.3-4.2 2.8 5.9 3-1.4-2.8-5.8H17z' transform='translate(2 2)' fill='%230a0a0b' fill-opacity='.85'/%3E%3Cpath d='M4 2v18l4.3-4.2 2.8 5.9 3-1.4-2.8-5.8H17z' fill='url(%23sun)'/%3E%3Cpath d='M4 2v18l4.3-4.2 2.8 5.9 3-1.4-2.8-5.8H17z' fill='none' stroke='%230a0a0b' stroke-width='1.2' stroke-linejoin='miter'/%3E%3C/svg%3E") 4 2, pointer;
  --cur-text: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='26'%3E%3Cg stroke='%230a0a0b' stroke-opacity='.5' stroke-width='4' stroke-linecap='round'%3E%3Cpath d='M9 4v18M5 4h8M5 22h8'/%3E%3C/g%3E%3Cg stroke='%23f5f5f7' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M9 4v18M5 4h8M5 22h8'/%3E%3C/g%3E%3C/svg%3E") 9 13, text;
  --cur-cross: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='26' height='26'%3E%3Cg stroke='%230a0a0b' stroke-opacity='.5' stroke-width='4' stroke-linecap='round'%3E%3Cpath d='M13 1v9M13 16v9M1 13h9M16 13h9'/%3E%3C/g%3E%3Cg stroke='%2365c0cd' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M13 1v9M13 16v9M1 13h9M16 13h9'/%3E%3C/g%3E%3C/svg%3E") 13 13, crosshair;
  --cur-inspect: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cg fill='none' stroke='%230a0a0b' stroke-opacity='.55' stroke-width='4' stroke-linecap='round'%3E%3Cpath d='M4 10V4h6M26 10V4h-6M4 20v6h6M26 20v6h-6'/%3E%3C/g%3E%3Cg fill='none' stroke='%2365c0cd' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M4 10V4h6M26 10V4h-6M4 20v6h6M26 20v6h-6'/%3E%3C/g%3E%3Ccircle cx='15' cy='15' r='1.8' fill='%23f37267'/%3E%3C/svg%3E") 15 15, zoom-in;
  --cur-prev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cg fill='none' stroke='%230a0a0b' stroke-opacity='.55' stroke-width='5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 7l-8 8 8 8'/%3E%3C/g%3E%3Cg fill='none' stroke='%23f5f5f7' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 7l-8 8 8 8'/%3E%3C/g%3E%3C/svg%3E") 15 15, w-resize;
  --cur-next: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cg fill='none' stroke='%230a0a0b' stroke-opacity='.55' stroke-width='5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 7l8 8-8 8'/%3E%3C/g%3E%3Cg fill='none' stroke='%23f5f5f7' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 7l8 8-8 8'/%3E%3C/g%3E%3C/svg%3E") 15 15, e-resize;
  --cur-close: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cg fill='none' stroke='%230a0a0b' stroke-opacity='.55' stroke-width='5' stroke-linecap='round'%3E%3Cpath d='M9 9l12 12M21 9L9 21'/%3E%3C/g%3E%3Cg fill='none' stroke='%23f5f5f7' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M9 9l12 12M21 9L9 21'/%3E%3C/g%3E%3C/svg%3E") 15 15, pointer;
  --sb-track: #000; --sb-thumb: #3a3a3c; --sb-thumb-hover: #545456;
}


/* ================================================================ 2 BASE */

html { background: var(--ground); color-scheme: dark; }
body { background: var(--ground); line-height: 1.47; letter-spacing: -0.022em; }
code, .fields .v, table, .lbm, .stat__v, .typeline__f, .tile__f, .tile__t, .lb__id {
  font-family: var(--code); letter-spacing: 0; }
.fields .v, td { font-variant-numeric: tabular-nums; }
/* links underline only in running text (CONTROLS: LINK). A card, a row or a
   chip is one big link, and underlining every word in it on hover is noise. */
a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: none; }

.display, .page-title, h1, h2, .launch-h, .chapter__h, .closing__h, .scrub, .gcta__h {
  font-family: var(--sans); font-weight: 700; letter-spacing: -0.035em; color: var(--lum-max); }
.display { font-size: clamp(3rem, 9vw, 6.5rem); line-height: 1.02; }
.page-title { font-size: clamp(2.4rem, 5vw, 3.5rem); line-height: 1.1; padding-bottom: 0.1em;
  background: linear-gradient(180deg, var(--lum-max) 30%, #b9b9be 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent; }
/* typed (site.js splits it into .ty spans): a parent's text-clipped gradient paints
   every descendant glyph whatever its opacity, so the untyped letters showed through.
   A typed title is solid, as one over a photograph already is (a per-letter gradient
   was tried: the clip dropped the bold). With script off the gradient stays. */
.page-title:has(.ty) { background: none; color: var(--lum-max); -webkit-background-clip: border-box;
  background-clip: border-box; }
h2, .launch-h, .chapter__h { font-size: clamp(2rem, 4.4vw, 3.5rem); line-height: 1.07; }
.cols--side h2 { font-size: clamp(1.5rem, 2.2vw, 2rem); line-height: 1.1; }   /* a side column's */
.lede, .lede--hero { font-size: clamp(1.2rem, 1.9vw, 1.65rem); line-height: 1.32; font-weight: 600;
  letter-spacing: -0.02em; color: var(--lum-max); max-width: 40rem; }
.lede--sub, .note, .launch-sub, .chapter__p { color: var(--dim); font-size: var(--t-body); line-height: 1.5; }

/* the sunset headline. Gradient text paints only inside its own box, so it
   gets room below the glyphs (descenders were being cut) and gives it back. */
.launch-h, .closing__h {
  background: var(--headline); background-size: 220% 100%; background-position: 0% 0;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  line-height: 1.12; padding-bottom: 0.12em; margin-bottom: calc(1.6rem - 0.12em);
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
  transition: background-position 1.8s var(--m-enter); }
.closing__h { margin-bottom: 0; }
.launch-h.swept, .closing__h.swept { background-position: 100% 0; }   /* site.js, once, on arrival */

/* the terminal's marks, off */
.chapter__h::before, .launch-h::before, .closing__h::after, .hero__cue::after,
.page-title::after, .display::after, .typeline__caret { display: none !important; content: none !important; }
.hero .typeline, .hero__cue { display: none; }
.lede--hero { border-left: 0; padding-left: 0; }
.masthead__role::before { content: ""; }

.section { padding-block: clamp(3.5rem, 9vw, 7rem); }
.section + .section { border-top: 0; }


/* ========================================================== 3 BEHAVIOURS */

/* LABEL -- the mono, uppercase, tracked. Every label, key and status. */
.eyebrow, .caveat__k, .fields .k, thead th, .stat__k, .legend, .lb__sub, .lbm dt, .jump__d,
.foot__meta dt, .foot__set h3, .foot__nav h2, .pcard__cat, .views a, .minutes a, .specs dt,
.usecard__k, .bento__tile figcaption b, .status-chip, .rail__count, .rail__cap, .chips a,
.announce__tag, .terms, .pfilm figcaption, .mread-toc__btn, .usb-out__k, .chat__status, .chat__who,
.chat__k, .chat__count {
  font-family: var(--code); text-transform: uppercase; letter-spacing: var(--track-caps);
  font-size: var(--t-label); font-weight: 500; }
.eyebrow { color: var(--dim); margin-bottom: 0.6rem; }
.eyebrow a { color: var(--lum-max); text-decoration: none; }
.eyebrow .cube { width: 1.35em; height: 1.35em; vertical-align: -0.38em; }
.terms { text-transform: none; letter-spacing: 0.03em; line-height: 1.7; }

/* SURFACE -- a rounded panel. The radius is on the box only, never a clip, so
   rounding can never cut text. */
.panel, .caveat, .gcta, .gcard, .stats > *, .player__note, .swatches > *, .mlab__grid > *,
.legend, .mspec, .mfig, .annot, .rt, .tablewrap, .lbm, .typeline, .book__spread, .specs,
.jump > a, .pdetail__views a, .bento__tile figcaption, .usecard figcaption, .explore__group,
.usb-card, .usb-tree, .usb-item, .usb-spec, .usb-group, .mread-toc, .chat {
  border-radius: var(--radius-m); }
.caveat, .gcard, .stats > *, .swatches > *, .mlab__grid > *, .jump > a, .specs, .tablewrap,
.player__note, .explore__group, .usb-card, .usb-tree, .usb-item, .usb-spec, .usb-group, .mread-toc, .chat {
  background-color: var(--surface); border: 1px solid var(--edge); }
.caveat, .gcta, .player__note, .swatches > *, .mspec, .annot, .rt { padding-inline: max(1rem, 1.1em); }
.status, .sw__chip, .minutes a, .views a, .slide__cap, .banner__ctl, .status-chip { border-radius: var(--pill); }
.jump > a, .tile__f, .m-step, .mlab__btn, .pdetail__views a { border-radius: var(--radius-s); }

/* FRAME -- a rounded picture: radius AND clip, so the image follows the corner.
   A figure with a caption is not a frame: its picture is, or the corner clips
   the caption's first letter (the book's plates read "late 39"). */
.pcard, .tile, .pdetail__img, .player__frame, .run-still, .m-still, .book__cover, .booklink__cover,
.plates__f img, .mfig img, .pdetail__views img, .pair img, .chapter__media, .bento__tile, .rail__item,
.places__item, .lb__fig img, .lb__fig video, .pfilm video, .package__media, .usb-item__pics img, .duo__frame,
.usb-film, .excerpt__frame {
  border-radius: var(--radius-l); overflow: hidden; }
.tile, .pair img, .pdetail__views img, .plates__f img, .mfig img, .usb-item__pics img, .duo__frame, .usb-film {
  border-radius: var(--radius-m); }
.pcard__img { border-radius: 0; }                 /* inside a clipped card: one radius, not two */
/* A caption inside a clipped frame keeps clear of the frame's corner: inset 0.7 of
   the radius, and seated high enough that the curve passes below the text. Tied to
   the radius, so changing a radius moves its captions with it. */
.tile { padding-bottom: 0.5rem; }
.tile__f { padding: 0.45rem calc(var(--radius-m) * 0.7) 0; }
.tile__t { padding: 0.1rem calc(var(--radius-m) * 0.7) 0; }
.rail__cap { padding: 0.8rem calc(var(--radius-l) * 0.7) 1.05rem; }

/* GROUP -- record.css draws hairlines between members by setting them on a
   grey backdrop with 1px gaps. Rounded members show that backdrop square at
   every corner, so here a group is space between surfaces. */
.pgrid, .jump, .stats, .swatches, .mlab__grid, .pair, .lb__fig .pair, .usb-grid, .usb-films__grid {
  gap: var(--gap); background: none; border: 0; }
.jump { gap: 0.5rem; }
.pgrid { padding-bottom: 1rem; }                  /* room for a lifted card's glow */
/* a card is card-sized however many share its row: auto-fill keeps the empty
   tracks, so a category of one (the onboarding package) is not stretched across
   the page (it was 1080 px wide, 2026-10-04) */
.pgrid { grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }

/* ROWS -- a label beside its value. The rule under a row is drawn by BOTH
   cells, so both must be the row's full height: a cell is never aligned
   inside its row (align-self), or the smaller label's rule rides higher than
   the value's. Text that should sit mid-row is centred inside its cell. */
:is(.specs, .fields, .lbm) > * { align-self: stretch; }
.specs > * { align-content: center; }

/* GLOW -- the sun, low, under the pointer. Panels light from their own
   background; picture tiles through an overlay (record.css [data-glow]::after)
   because a picture covers the background. site.js sets --mx/--my on any of
   these; --glow fades in on hover. */
/* listed with :hover too: record.css sets hover backgrounds with the `background`
   shorthand, which resets background-image -- the glow vanished exactly on hover */
:is(.pcard, .gcard, .caveat, .jump > a, .specs, .explore__group, .usb-card, .usb-item, .usb-spec, .usb-group, .mread-toc),
:is(.pcard, .gcard, .caveat, .jump > a, .specs, .explore__group, .usb-card, .usb-item, .usb-spec, .usb-group, .mread-toc):hover {
  background-image: radial-gradient(var(--glow-size) circle at var(--mx, 50%) var(--my, 50%),
    rgba(243, 114, 103, calc(var(--glow) * 0.15)), rgba(251, 208, 64, calc(var(--glow) * 0.05)) 40%,
    transparent 70%);
  transition: --glow var(--m-slow) var(--m-enter), transform var(--m-base) var(--m-enter),
    box-shadow var(--m-base) var(--m-enter), background-color var(--m-fast) linear,
    border-color var(--m-fast) linear; }
[data-glow]::after { background: radial-gradient(var(--glow-size) circle at var(--mx, 50%) var(--my, 50%),
  var(--glow-core), var(--glow-halo) 35%, transparent 65%); }
@media (hover: hover) {
  .pcard:hover, .gcard:hover, .caveat:hover, .jump > a:hover, .specs:hover, .explore__group:hover,
  .usb-card:hover, .usb-item:hover, .usb-spec:hover, .usb-group:hover, .mread-toc:hover { --glow: 1; }
  .pcard:hover, .usb-card:hover, .usb-item:hover { transform: translateY(var(--lift)); box-shadow: var(--lift-shadow);
    background-color: var(--surface-hover); }
  .bento__tile:hover, .rail__item:hover { box-shadow: var(--lift-shadow); }
  .jump > a:hover { border-color: var(--rule); background-color: var(--surface-hover); text-decoration: none; }
}

/* CONTROLS -- four kinds, one set of states.
   PRIMARY   .bookbuy .buy .localnav__cta   the light object on the dark page;
             on hover it brightens and the sun glows behind it
   SECONDARY .ctas__alt                     the outlined pill beside a primary
   ICON      .rail__btn .banner__pause .theme-toggle   a round glass button
   LINK      running text: the cube's cyan, underlined on hover
   States everywhere: press scales to --press; focus is a cyan ring 3px out;
   disabled drops to 35% and stops responding; 44px wherever tapped. */
.bookbuy, .buy, .ctas__alt, .localnav__cta {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem;
  border-radius: var(--pill); font-family: var(--sans); font-weight: 600; letter-spacing: -0.012em;
  text-decoration: none; white-space: nowrap; margin: 0;
  transition: background var(--m-fast) linear, box-shadow var(--m-base) var(--m-enter),
    border-color var(--m-fast) linear, transform var(--m-fast) var(--m-enter); }
.bookbuy, .buy, .ctas__alt { min-height: var(--ctl-h); padding: 0 1.35rem; font-size: 1rem; }
.localnav__cta { min-height: var(--ctl-h-s); padding: 0 1rem; font-size: 0.8rem; }
.bookbuy, .buy, .localnav__cta,
.closing--image .bookbuy, .hero--image .bookbuy {
  background: var(--btn-bg); color: var(--btn-fg); border: 0; filter: none;
  -webkit-backdrop-filter: none; backdrop-filter: none; }
.bookbuy:hover, .buy:hover, .localnav__cta:hover {
  background: var(--btn-bg-hover); color: var(--btn-fg); text-decoration: none; box-shadow: var(--btn-glow); }
.ctas__alt { background: transparent; color: var(--lum-max); border: 1px solid var(--btn2-edge); }
.ctas__alt::after { content: none; }
.ctas__alt:hover { color: var(--lum-max); background: var(--btn2-hover); border-color: var(--lum-max);
  text-decoration: none; }
.bookbuy span[aria-hidden] { display: inline-block; transition: transform var(--m-base) var(--m-enter); }
.bookbuy:hover span[aria-hidden] { transform: translateX(3px); }

.rail__btn, .banner__pause, .theme-toggle, .usb-film__play {
  background: var(--icon-bg); color: var(--lum-max); border: 1px solid var(--edge); border-radius: 50%;
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  transition: background var(--m-fast) linear, transform var(--m-fast) var(--m-enter); }
.rail__btn:hover, .banner__pause:hover, .theme-toggle:hover, .usb-film:hover .usb-film__play {
  background: var(--icon-hover); }
.rail__btn { width: var(--ctl-h); height: var(--ctl-h); }

.prose a, .note a, .lede a, .caveat a, .fields a, .specs a {
  color: var(--link); text-decoration: underline; text-decoration-color: transparent;
  text-underline-offset: 0.18em; transition: text-decoration-color var(--m-fast) linear; }
.prose a:hover, .note a:hover, .lede a:hover, .caveat a:hover, .fields a:hover, .specs a:hover {
  text-decoration-color: currentColor; }

.bookbuy:active, .buy:active, .ctas__alt:active, .localnav__cta:active, .rail__btn:active,
.theme-toggle:active, .banner__pause:active { transform: scale(var(--press)); }
.buy--off, .bookbuy[aria-disabled="true"], button:disabled { opacity: 0.35; pointer-events: none; }
a:focus-visible, button:focus-visible, [tabindex]:focus-visible, summary:focus-visible, .pcard:focus-visible,
.chat__input:focus-visible {
  outline: 2px solid var(--focus); outline-offset: 3px; }
.ripple { background: rgba(10, 10, 11, 0.16); }


/* ================================================================ 4 BARS */

/* THE HAZE -- every page carries the sun at its top edge and its foot: the
   emblem's horizontal gradient, fading into the black. Screen-blended, so on
   black it is coloured light and over a photograph only a faint haze; it
   never sits on text as a stripe. Pointer-transparent, purely atmosphere. */
body { position: relative; min-height: 100vh; }
body::before, body::after {
  content: ""; position: absolute; left: 0; right: 0; z-index: 35; pointer-events: none;
  background: var(--sunset); opacity: var(--haze); mix-blend-mode: screen; }
body::before { top: 0; height: var(--haze-top);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0,0,0,0.35) 30%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0%, rgba(0,0,0,0.35) 30%, transparent 100%); }
/* the foot is the setting sun: the emblem's black stripes cut across it, the
   gaps widening toward the bottom edge as they do on the mark. Two masks,
   intersected: the fade, and the stripes. */
body::after { bottom: 0; height: var(--haze-bottom);
  -webkit-mask-image:
    linear-gradient(0deg, #000 0%, rgba(0,0,0,0.35) 35%, transparent 100%),
    linear-gradient(0deg, #000 0 18px, transparent 18px 28px, #000 28px 52px, transparent 52px 60px,
      #000 60px 86px, transparent 86px 92px, #000 92px 118px, transparent 118px 122px,
      #000 122px 146px, transparent 146px 148px, #000 148px);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(0deg, #000 0%, rgba(0,0,0,0.35) 35%, transparent 100%),
    linear-gradient(0deg, #000 0 18px, transparent 18px 28px, #000 28px 52px, transparent 52px 60px,
      #000 60px 86px, transparent 86px 92px, #000 92px 118px, transparent 118px 122px,
      #000 122px 146px, transparent 146px 148px, #000 148px);
  mask-composite: intersect; }

/* the ambient: the sun, glowing in from the edges all the way down every page.
   One tile, a screen and a half tall, repeated for the page's whole length --
   so a long page on a phone is lit as evenly as a short one on a desktop.
   Each glow is anchored at an edge (coral left, magenta right, gold left) and
   sized from the viewport, so it reaches in and brushes the text column's
   edges without sitting under the words. A faint magenta wash runs down the
   middle for depth. Solid bands (heroes, cards) sit over it; open black shows it. */
body {
  background-color: var(--ground);
  background-image:
    radial-gradient(ellipse var(--amb-w) 22% at 0% 16%, rgba(243, 114, 103, calc(var(--ambient) * 0.16)), transparent 70%),
    radial-gradient(ellipse var(--amb-w) 22% at 100% 50%, rgba(237, 4, 152, calc(var(--ambient) * 0.14)), transparent 70%),
    radial-gradient(ellipse var(--amb-w) 22% at 0% 84%, rgba(251, 208, 64, calc(var(--ambient) * 0.105)), transparent 70%),
    linear-gradient(90deg, transparent 0%, rgba(237, 4, 152, calc(var(--ambient) * 0.025)) 50%, transparent 100%);
  background-size: 100% var(--amb-tile), 100% var(--amb-tile), 100% var(--amb-tile), 100% 100%;
  background-repeat: repeat-y, repeat-y, repeat-y, no-repeat; }

/* The masthead's first row is exactly --bar-h tall and everything in it centres
   on that line: the cube, the name, the links, the menu button. The burger is
   placed from the same token (not from the bar's padding), and inset so its
   rules END at the page gutter -- the mirror of the cube, which STARTS there. */
.masthead { background: var(--bar); -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px); border-bottom: 1px solid var(--bar-edge);
  font-family: var(--sans); font-size: 0.75rem; padding-block: 0; align-items: center;
  min-height: var(--bar-h); }
.masthead__id { align-items: center; height: var(--bar-h); }
.masthead__name, .masthead__role { line-height: 1; }
.masthead__name { font-weight: 600; letter-spacing: -0.01em; color: var(--lum-max); }
.masthead__role { color: var(--dim); }
.nav { align-self: center; }
@media (max-width: 59.99rem) {
  .nav-burger { width: var(--burger); height: var(--burger);
    top: calc((var(--bar-h) - var(--burger)) / 2);
    right: calc(var(--gut) - (var(--burger) - var(--burger-line)) / 2); }
  .nav-burger span, .nav-burger span::before, .nav-burger span::after { width: var(--burger-line); }
  .masthead { padding-right: calc(var(--gut) + var(--burger)); }
  /* the burger's room is for the top row only: the opened menu takes it back,
     so its rules end at the gutter like everything else */
  .nav { margin-right: calc(-1 * var(--burger)); width: calc(100% + var(--burger)); }
}
.progress span { background: var(--headline); }
.nav a { color: var(--lum-max); opacity: 0.8; }
.nav a:hover { opacity: 1; text-decoration: none; color: var(--lum-max); }
.nav a[aria-current="page"] { color: var(--lum-max); opacity: 1; font-weight: 600; }
.nav a[aria-current="page"]::before { content: none; }

.theme-toggle { align-self: center; width: 1.6rem; height: 1.6rem; padding: 0; margin-left: 0.4rem;
  display: grid; place-items: center; }
.theme-toggle[hidden] { display: none; }
.theme-toggle span { width: 0.8rem; height: 0.8rem; border-radius: 50%;
  background: linear-gradient(90deg, var(--lum-max) 50%, transparent 50%); box-shadow: 0 0 0 1.5px var(--lum-max); }
@media (max-width: 59.99rem) {     /* on a phone: in the bar, beside the menu button */
  .theme-toggle { position: absolute; top: 50%; right: calc(var(--gut) + 2.9rem); transform: translateY(-50%); margin: 0; }
}

.localnav { background: var(--bar-2); border-bottom-color: var(--bar-edge); font-family: var(--sans); }
.localnav__id { font-size: 1.15rem; letter-spacing: -0.02em; }
.localnav__links a { color: var(--lum-max); opacity: 0.7; font-size: 0.8rem; }
.localnav__links a:hover, .localnav__links a.is-here { opacity: 1; text-decoration: none; }

.announce { background: var(--band); border-bottom-color: var(--rule-soft); }
.announce__t { color: var(--text); }
.lamp { background: var(--lamp); }

.foot { background: var(--surface); font-family: var(--sans); font-size: 0.75rem; color: var(--dim);
  border-top: 0; position: relative; }
.foot::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: var(--sunset); opacity: 0.8; }
.foot__big { font-family: var(--sans); font-weight: 600; color: var(--lum-max); }
.foot__lede, .foot__set a, .foot__nav a { color: var(--text); }
.foot__set a:hover, .foot__nav a:hover { color: var(--lum-max); }


/* ============================================================ 5 SECTIONS */

/* the home hero and the close: black bands, whatever the theme */
.hero, .closing { background: #000; color: var(--lum-max); }
.hero { align-items: center; text-align: center; }
.hero .display, .hero .lede--hero, .hero .eyebrow { text-shadow: none; }
.hero .lede--sub, .closing .closing__p { color: #a1a1a6; text-shadow: none; }
.hero__emblem, .hero .lede, .hero .lede--sub { margin-inline: auto; }
.hero .ctas { justify-content: center; }
.hero__media::after { background: linear-gradient(180deg, rgba(0,0,0,0.35) 0%, rgba(0,0,0,0.2) 40%, #000 100%); }
.closing { border-top: 0; }
.closing__media::after { background: radial-gradient(ellipse at 50% 55%, rgba(0,0,0,0.35), #000 78%); }

/* every page's header: the sun rising faintly behind, a sun rule beneath */
main > .section--flush:first-child, main > .pagehero:first-child { position: relative; }
main > .section--flush:first-child:not(.pagehero--image) {
  background: radial-gradient(ellipse 80% 120% at 50% -30%, rgba(243, 114, 103, 0.14), transparent 60%);
  padding-top: clamp(3.5rem, 9vw, 6rem); }
main > .section--flush:first-child::after, main > .pagehero:first-child::after {
  content: ""; position: absolute; left: max(var(--gut), calc((100vw - var(--max)) / 2 + var(--gut)));
  bottom: 0; width: min(10rem, 30vw); height: 2px; background: var(--sunset); border-radius: 2px; }
.pagehero--image .page-title { background: none; color: #f5f5f7; -webkit-background-clip: border-box;
  background-clip: border-box; }
.pagehero--image .lede { color: #f5f5f7; }

/* READER -- the manual, read on one page (facility.py manual_reader: the
   site's shop/facility-manual/read.html and the drive's manual.html). Its
   contents in a column on the left, held while the text scrolls; on a phone,
   a "Contents" control at the top that opens the list -- a checkbox, so it
   works with scripting off; site.js marks the part on screen. The column is a
   SURFACE with GLOW (.mread-toc in those lists); the text is not a panel. */
.mread { display: grid; gap: clamp(1.5rem, 4vw, 3.5rem); align-items: start; }
.mread__text { min-width: 0; max-width: 46rem; }
.mread-toc { padding: 1rem 1.1rem; }
.mread-toc__check { position: absolute; width: 1px; height: 1px; opacity: 0; }
.mread-toc__btn { display: flex; align-items: center; justify-content: space-between; cursor: pointer; color: var(--lum-max); }
.mread-toc__btn::after { content: "+"; font-size: 1.1rem; color: var(--dim); }
.mread-toc__check:checked ~ .mread-toc__btn::after { content: "\2212"; }
.mread-toc__check:focus-visible ~ .mread-toc__btn { outline: 2px solid var(--focus); outline-offset: 3px; }
.mread-toc__list { list-style: none; margin: 0.8rem 0 0; padding: 0; display: none; }
.mread-toc__check:checked ~ .mread-toc__list { display: block; }
.mread-toc__list a {
  display: block; padding: 0.4rem 0 0.4rem 0.8rem; border-left: 2px solid transparent;
  color: var(--text); text-decoration: none; font-size: var(--t-data); line-height: 1.35;
}
.mread-toc__list a:hover { color: var(--lum-max); }
.mread-toc__list a[aria-current="true"] { color: var(--lum-max); border-left-color: var(--sun-2); }
/* Two rows on a wide screen: the first part's opening (row 1, column 2), then
   the contents column and the rest of the text side by side (row 2), so the
   column's top meets the text's first panel. Row 2 holds the whole read, so
   the column stays held to its end. On a phone the order is the markup's: the
   contents control first, then the opening, then the text. */
.mread { row-gap: 0; }
.mread__text > .mread-part--cont > .prose > :first-child { margin-top: 0; }
@media (min-width: 60rem) {
  .mread { grid-template-columns: 15rem minmax(0, 1fr); }
  .mread__head { grid-column: 2; grid-row: 1; }
  .mread-toc { grid-column: 1; grid-row: 2; align-self: start; }
  .mread__text { grid-column: 2; grid-row: 2; }
  .mread-toc {
    position: sticky; top: calc(var(--bar-h) + 1.25rem);
    max-height: calc(100vh - var(--bar-h) - 2.5rem); overflow-y: auto;
  }
  .mread-toc__btn { display: none; }
  .mread-toc__list { display: block; margin-top: 0; }
}
.mread [id] { scroll-margin-top: calc(var(--bar-h) + 1.25rem); }
.mread-part + .mread-part { border-top: 1px solid var(--rule-soft); margin-top: clamp(2.5rem, 6vw, 4.5rem);
  padding-top: clamp(2.5rem, 6vw, 4.5rem); }
.mread-part__t { margin: 0 0 0.6rem; }
/* the manual's own headings sit under its section titles, not beside them */
.mread .manual h2 { font-size: clamp(1.35rem, 2.4vw, 1.75rem); margin-top: 2.4rem; }
/* the end mark (record.css .endmark): its foot meets the contents column's foot */
.mread__text .endmark { margin-bottom: 0; }

/* the statement: lit word by word (site.js); the last word is the sun */
.scrub { font-size: clamp(2.4rem, 6.4vw, 5rem); letter-spacing: -0.04em; line-height: 1.05; max-width: 16ch; }
.js-scrub .scrub .w { color: var(--dimword); }
.js-scrub .scrub .w.lit { color: var(--lum-max); }
.js-scrub .scrub .w.lit:last-child, .scrub .w:last-child {
  background: var(--headline); -webkit-background-clip: text; background-clip: text; color: transparent; }


/* ========================================================== 6 COMPONENTS */

.bento__tile, .rail__item, .chapter__media, .places__item, .pcard { background-color: var(--surface); }
.bento__tile figcaption { background: var(--glass); color: var(--text); border: 1px solid var(--edge);
  font-family: var(--sans); font-size: 0.95rem; line-height: 1.35; }
.bento__tile figcaption b { display: block; margin-bottom: 0.15rem; color: var(--lum-max); font-weight: 600; }

.usecard { position: relative; }
.usecard::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px; z-index: 3;
  background: var(--sunset); transform: scaleX(0); transform-origin: 0 50%;
  transition: transform var(--m-slow) var(--m-enter); }
@media (hover: hover) { .usecard:hover::before { transform: scaleX(1); } }
.usecard__k a { color: var(--lum-max); text-decoration: none; }
.usecard__h { font-family: var(--sans); font-weight: 700; }

.specs { padding: 0.4rem clamp(1.1rem, 3vw, 2rem); grid-template-columns: minmax(8rem, 15rem) 1fr; border-top: 1px solid var(--edge); }
.specs dt, .specs dd { padding: 1.05rem 0; border-bottom: 1px solid var(--rule-soft); }
.specs dt { color: var(--dim); padding-right: 1.5rem; }
.specs dd { font-family: var(--sans); font-size: clamp(1.05rem, 1.6vw, 1.3rem); color: var(--lum-max); }
.specs dt:last-of-type, .specs dd:last-of-type { border-bottom: 0; }
@media (max-width: 40rem) {
  .specs { grid-template-columns: 1fr; }
  .specs dt { padding-bottom: 0.2rem; border-bottom: 0; }
  .specs dd { padding-top: 0; }
}

.caveat__k::before { color: var(--sun-2); }
.gcard { padding: 1.4rem clamp(1rem, 2.4vw, 1.8rem); margin-bottom: 1rem; border-radius: var(--radius-l); }
.jump > a { padding: 0.85rem 1rem 0.85rem 1.6rem; }
.stat__v { font-family: var(--sans); font-weight: 700; letter-spacing: -0.03em; color: var(--lum-max); }
thead th { color: var(--dim); background: var(--surface); }
table { border-collapse: separate; border-spacing: 0; }
.tablewrap { overflow-x: auto; overflow-y: hidden; }
/* a table on a SURFACE: the panel's inside edge is the cells' padding, the same
   inset as a caveat's, so no column touches the rounded edge (manual tables) */
.tablewrap { --cell-in: max(1rem, 1.1em); }
.tablewrap :is(th, td):first-child { padding-left: var(--cell-in); }
.tablewrap :is(th, td):last-child { padding-right: var(--cell-in); }
.tablewrap thead th { padding-top: 0.85rem; }
.tablewrap tr:first-child > :is(th, td) { border-top: 0; }
.tablewrap tbody tr:last-child > td { padding-bottom: 0.75rem; }
.pdetail__price { font-family: var(--code); letter-spacing: 0.02em; }


/* the design system page (facility.py page_system): layouts for its specimens */
.sys-marks, .sys-grid, .sys-motion { display: grid; gap: 1.2rem;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); align-items: start; }
.sys-grid > .sys-wide { grid-column: 1 / -1; }   /* a specimen that needs a page's width */
.sys-mark { margin: 0; padding: 1.4rem; border-radius: var(--radius-l); background-color: var(--surface);
  border: 1px solid var(--edge); display: grid; gap: 1rem; justify-items: center; text-align: center; }
.sys-mark img { width: 9rem; height: auto; }
.sys-mark__cube .cube { width: 4.5rem; height: 4.5rem; }
.sys-mark .sundivider { padding: 0; }
.sys-mark figcaption, .sys-swatch span, .sys-cursor span { color: var(--dim); font-size: var(--t-data); }
.sys-swatches { display: grid; gap: 0.8rem; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); }
.sys-swatch { margin: 0; border-radius: var(--radius-m); background-color: var(--surface);
  border: 1px solid var(--edge); overflow: hidden; }
.sys-swatch__chip { display: block; height: 4.5rem; border-bottom: 1px solid var(--edge); }
.sys-swatch figcaption { padding: 0.7rem 0.9rem; display: grid; gap: 0.15rem; }
.sys-swatch b, .sys-cursor b { font-family: var(--code); font-size: var(--t-label); text-transform: uppercase;
  letter-spacing: var(--track-caps); color: var(--lum-max); }
.sys-swatch code { font-family: var(--code); font-size: var(--t-label); color: var(--text); }
.sys-type { display: grid; gap: 1.6rem; }
.sys-type > div { border-top: 1px solid var(--rule-soft); padding-top: 1rem; }
.sys-frame { max-width: 20rem; }
.sys-motion .usecard { max-width: 22rem; }
.sys-pgrid { margin-top: 0; max-width: 18rem; }
.sys-cursors { display: grid; gap: 0.8rem; grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
  margin-top: 1.4rem; }
.sys-cursor { display: grid; gap: 0.3rem; padding: 1.4rem 1rem; border-radius: var(--radius-m);
  background-color: var(--surface); border: 1px dashed var(--rule); }
.sys-link { color: var(--link); text-decoration: underline; text-decoration-color: transparent;
  text-underline-offset: 0.18em; align-self: center; }
.sys-link:hover { text-decoration-color: currentColor; }

@media (min-width: 60rem) { :root { --amb-w: 46%; } }

/* the credential page (facility.py page_credential, site.js credential) */
.cred { display: grid; gap: clamp(1.6rem, 5vw, 4rem); align-items: start; }
@media (min-width: 52rem) { .cred { grid-template-columns: minmax(0, 1fr) minmax(0, 24rem); } }
.cred__label { display: block; margin-bottom: 0.6rem; font-family: var(--code); font-size: var(--t-label);
  text-transform: uppercase; letter-spacing: var(--track-caps); color: var(--dim); }
.cred__input { width: 100%; min-height: var(--ctl-h); padding: 0 1.1rem; border-radius: var(--radius-m);
  background: var(--surface); border: 1px solid var(--edge); color: var(--lum-max);
  font-family: var(--code); font-size: 1.05rem; letter-spacing: 0.08em; text-transform: uppercase; }
.cred__input::placeholder { color: var(--dim); text-transform: none; letter-spacing: 0; font-family: var(--sans); }
.cred__input:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.cred__ctas { margin-top: 1rem; }
.cred__issued { font-family: var(--code); font-size: var(--t-label); text-transform: uppercase;
  letter-spacing: var(--track-caps); color: var(--sun-2); min-height: 1.2em; }
.cred__card { margin: 0; display: grid; gap: 0.8rem; justify-items: center; }
.cred__card img, .cred__card canvas { width: 100%; max-width: 22rem; height: auto; border-radius: var(--radius-l);
  filter: drop-shadow(0 24px 50px rgba(243, 114, 103, 0.22)); }
.cred__card canvas { aspect-ratio: 54 / 86; }
/* a control styled as a pill sets display, which would beat [hidden]: without
   scripting, the issue and save buttons must not show and do nothing */
.cred [hidden] { display: none !important; }

/* ASK -- a visitor makes a request and the facility answers (facility.py
   page_ask, static/js/ask.js). One SURFACE holding a transcript laid out as
   ROWS-like pairs: the label (LABEL) beside what was said. The facility's
   answer is the content, so it is the brightest text in the panel; a request
   is body text; a notice is plain body text under its own label, never in the
   facility's styling; a line from the page itself (queued, not delivered) is
   dim and unlabelled. The lamp says the state: green and pulsing while
   requests are taken, breathing slowly while one is worked on, hueless when
   closed. Nothing here is red: red is for leaving. */
.chat { position: relative; padding: clamp(1rem, 3vw, 1.75rem); border-radius: var(--radius-l); }
.chat [hidden] { display: none !important; }      /* a pill sets display, which beats [hidden] */
.chat__bar { display: flex; align-items: center; min-height: var(--ctl-h); }
.chat__status { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.3rem 0.6rem; margin: 0;
  color: var(--text); }
.chat__status > span + span + span::before { content: "/"; margin-right: 0.6rem; color: var(--rule); }
.chat__id { color: var(--lum-max); }
.chat__lamp { flex: none; }
.chat:is([data-state="checking"], [data-state="closed"]) .chat__bar .chat__lamp {
  background: var(--dim); box-shadow: none; animation: none; opacity: 0.6; }
.chat__reset { min-height: var(--ctl-h); padding: 0 0.2rem; background: none; border: 0; color: var(--dim);
  font: 500 0.875rem/1 var(--sans); letter-spacing: -0.01em; cursor: var(--cur-link);
  transition: color var(--m-fast) linear; }
.chat__reset:hover { color: var(--lum-max); }
.chat__reset:active { transform: scale(var(--press)); }

.chat__log { list-style: none; margin: 0; padding: 0; }
.chat__log:not(:empty) { margin-top: 0.75rem; border-top: 1px solid var(--rule-soft); }
/* the front page's sample exchange: the chat's own type, without its controls */
.chat--sample { max-width: 46rem; margin: clamp(1.25rem, 3vw, 2rem) 0; }
.chat--sample .chat__log:not(:empty) { margin-top: 0; border-top: 0; }
.chat__msg { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr); gap: 0.35rem 1.25rem;
  padding: 1.15rem 0; border-bottom: 1px solid var(--rule-soft); }
.chat__who { margin: 0; padding-top: 0.4em; color: var(--dim); }
.chat__msg--nbd .chat__who { color: var(--lum-max); }
.chat__text { min-width: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.chat__msg--req .chat__text, .chat__msg--notice .chat__text, .chat__msg--sys .chat__text {
  color: var(--text); font-size: var(--t-body); line-height: 1.5; }
.chat__msg--nbd .chat__text { color: var(--lum-max); font-size: clamp(1.1rem, 1.7vw, 1.3rem); line-height: 1.42;
  font-weight: 500; letter-spacing: -0.016em; }
.chat__msg--sys .chat__text { grid-column: 2; color: var(--dim); }
.chat__msg--notice .chat__text a { color: var(--link); text-decoration: underline; text-underline-offset: 0.18em; }
.chat__working { display: inline-flex; align-items: center; gap: 0.7rem; margin: 0; color: var(--dim);
  font-size: var(--t-body); font-weight: 400; letter-spacing: -0.01em; white-space: normal; }
.chat__working .chat__lamp, .chat[data-state="working"] .chat__bar .chat__lamp { box-shadow: none; animation: none; }
@media (max-width: 40rem) {
  .chat__msg { grid-template-columns: minmax(0, 1fr); }
  .chat__who { padding-top: 0; }
  .chat__msg--sys .chat__text { grid-column: 1; }
}

.chat__k { display: block; margin: 0 0 0.75rem; color: var(--dim); }
.chat__start { margin-top: 1.1rem; }
.chat__asks { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.5rem; }
.chat__ask { font-size: 0.95rem; font-weight: 500; padding: 0.55rem 1.1rem; white-space: normal;
  text-align: left; line-height: 1.25; cursor: var(--cur-link); }
.chat__form { margin-top: 1.4rem; }
.chat__form:has(.chat__reset:not([hidden])) { margin-bottom: -0.6rem; }
.chat__row { display: flex; align-items: flex-end; gap: 0.6rem; }
.chat__input { flex: 1; min-width: 0; min-height: var(--ctl-h); max-height: 12.5rem; margin: 0; resize: none;
  padding: 0.62rem 1.1rem; border-radius: calc(var(--ctl-h) / 2); background: var(--ground);
  border: 1px solid var(--rule); color: var(--lum-max); font: 400 1rem/1.45 var(--sans); letter-spacing: -0.01em;
  cursor: var(--cur-text); transition: border-color var(--m-fast) linear; }
.chat__input:hover { border-color: var(--dim); }
.chat__input::placeholder { color: var(--dim); opacity: 1; }
.chat__send { flex: none; cursor: var(--cur-link); }
.chat__tools { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-top: 0.25rem; }
.chat__count:empty { display: none; }
.chat__count { margin: 0; padding-left: 1.1rem; color: var(--dim); }
.chat__reset { margin-left: auto; }
.chat__closed { margin-top: 1rem; }
.chat__closed-t { margin: 0 0 1.1rem; color: var(--lum-max); font-size: clamp(1.1rem, 1.7vw, 1.3rem);
  font-weight: 500; letter-spacing: -0.016em; }
.chat__live { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.chat__print { margin-top: 1.25rem; font-size: 0.875rem; line-height: 1.5; max-width: 38rem; }
.chat + .note { margin-top: 1.25rem; }
@media (prefers-reduced-motion: no-preference) {
  .chat__msg--in { animation: chat-in var(--reveal-dur) var(--ease-calm); }
  /* travel only, never opacity: an entry is readable even if its motion never runs */
  @keyframes chat-in { from { transform: translateY(8px); } }
  /* working: the lamp breathes, slowly -- a building at rest, not a spinner */
  .chat__working .chat__lamp, .chat[data-state="working"] .chat__bar .chat__lamp {
    animation: chat-breathe 3.2s ease-in-out infinite; }
  @keyframes chat-breathe { 50% { opacity: 0.25; } }
}
@media (prefers-reduced-motion: reduce) {
  /* the loops stop (record.css's backstop would otherwise run them at 1ms: a strobe) */
  .chat .lamp, .chat__msg--in { animation: none !important; }
}

/* =============================================================== 7 THEMES */

/* light: the same system, its tokens inverted */
:root[data-theme="light"] {
  color-scheme: light;
  --ground: #fbfbfd; --ground-2: #f5f5f7; --ground-3: #e8e8ed;
  --rule: #d2d2d7; --rule-soft: #e8e8ed;
  --dim: #6e6e73; --text: #1d1d1f; --lum-max: #1d1d1f;
  --cyan: #1b7c89; --link: #1b7c89; --focus: #1b7c89;   /* the cube's cyan, deep enough on white */
  --new: #bf4800; --lamp: #1aa260;
  --surface: #ffffff; --surface-hover: #f5f5f7;
  --edge: rgba(0, 0, 0, 0.07); --glass: rgba(255, 255, 255, 0.72);
  --glow-core: rgba(243, 114, 103, 0.12); --glow-halo: rgba(251, 208, 64, 0.04);
  --lift-shadow: 0 18px 40px rgba(243, 114, 103, 0.16);
  --btn-bg: #1d1d1f; --btn-fg: #fbfbfd; --btn-bg-hover: #000000;
  --btn-glow: 0 10px 30px rgba(243, 114, 103, 0.30);
  --btn2-edge: rgba(29, 29, 31, 0.28); --btn2-hover: rgba(29, 29, 31, 0.05);
  --icon-bg: rgba(255, 255, 255, 0.82); --icon-hover: rgba(255, 255, 255, 0.98);
  --bar: rgba(251, 251, 253, 0.80); --bar-2: rgba(251, 251, 253, 0.72); --bar-edge: rgba(0, 0, 0, 0.08);
  --band: #f0f0f3; --dimword: #d2d2d7;
  --sb-track: #fbfbfd; --sb-thumb: #c7c7cc; --sb-thumb-hover: #aeaeb2;
}
:root[data-theme="light"] .page-title { background: linear-gradient(180deg, #1d1d1f 30%, #48484d 100%);
  -webkit-background-clip: text; background-clip: text; }
:root[data-theme="light"] .bento__tile, :root[data-theme="light"] .rail__item,
:root[data-theme="light"] .chapter__media { box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05); }

/* the bands (home hero, close, page heroes) are black in BOTH themes: they keep
   the dark tokens, controls included */
.hero, .closing, .pagehero--image {
  --lum-max: #f5f5f7; --text: #d2d2d7; --dim: #a1a1a6; --new: #f5a623; --link: #65c0cd; --focus: #65c0cd;
  --btn-bg: #f5f5f7; --btn-fg: #0a0a0b; --btn-bg-hover: #ffffff;
  --btn-glow: 0 10px 34px rgba(243, 114, 103, 0.28), 0 0 0 1px rgba(255, 255, 255, 0.5);
  --btn2-edge: rgba(245, 245, 247, 0.30); --btn2-hover: rgba(245, 245, 247, 0.08);
  --icon-bg: rgba(51, 51, 54, 0.72); --icon-hover: rgba(80, 80, 84, 0.85);
  --glass: rgba(29, 29, 31, 0.72); --edge: rgba(255, 255, 255, 0.08);
  color: #f5f5f7; }


/* =============================================================== 8 MOTION */

/* ARRIVAL -- everything the reveal list in site.js tags .rv. The script is the
   one list; this is the one look. Hidden only once the script is running
   (.js-reveal), and only until the element arrives (.in). */
@media (prefers-reduced-motion: no-preference) {
  .js-reveal .rv:not(.in) { opacity: 0; transform: translateY(var(--rise)); }
  .js-reveal .rv[data-reveal="zoom"]:not(.in) { transform: translateY(var(--rise)) scale(1.03); }
  .js-reveal .rv {
    transition:
      opacity var(--reveal-dur) var(--ease-calm) calc(min(var(--n, 0), 5) * var(--stagger)),
      transform var(--reveal-dur) var(--ease-calm) calc(min(var(--n, 0), 5) * var(--stagger)); }
  /* arrived: weightless (:where), so a component's own hover transform -- a
     card's lift -- still wins over it */
  :where(.js-reveal .rv.in) { opacity: 1; transform: none; }
  /* a card that has arrived still lifts on hover, at the hover's own pace */
  .js-reveal :is(.pcard, .usb-card, .usb-item).rv.in { transition: --glow var(--m-slow) var(--m-enter),
    transform var(--m-base) var(--m-enter), box-shadow var(--m-base) var(--m-enter),
    background-color var(--m-fast) linear; }
}

/* IMAGES -- wait over the frame's surface, then fade in (site.js images()) */
@media (prefers-reduced-motion: no-preference) {
  .js-img img.img-wait { opacity: 0; }
  .js-img img.img-in { transition: opacity var(--img-dur) var(--ease-calm); }
  .js-img img.img-now { transition: none; }          /* arrived in a hidden tab */
  /* the frame a picture is waiting in breathes, faintly, so it reads as loading */
  :is(.pcard__img, .bento__tile, .rail__item, .chapter__media, .places__item, .pdetail__img,
      .pagehero__media, .hero__media, .tile):has(> img.img-wait, > * > img.img-wait) {
    background-image: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, 0.045) 50%, transparent 70%);
    background-size: 220% 100%; animation: img-wait 1.6s linear infinite; }
  @keyframes img-wait { from { background-position: 120% 0; } to { background-position: -120% 0; } }
}

/* BREATHE -- a picture under the pointer swells, slowly */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .bento__tile img, .places__item img, .chapter__media img, .rail__item img, .pcard__img img {
    transition: transform var(--breathe-dur) var(--ease-calm), opacity var(--img-dur) var(--ease-calm); }
  .bento__tile:hover img, .places__item:hover img, .chapter__media:hover img,
  .rail__item:hover img, .pcard:hover .pcard__img img { transform: scale(var(--breathe)); }
}

@media (prefers-reduced-motion: reduce) {
  .pcard, .gcard, .caveat, .jump > a, .specs, .usb-card, .usb-item, .usb-spec, .usb-group, .mread-toc, .launch-h, .closing__h { transition: none; }
}

/* FILMS -- a product's moving pictures (build.py page_product `films`) and the home
   page's onboarding package. A video is a picture: full width, its own black. */
.pfilms { display: grid; gap: var(--gap); }
.pfilm { margin: 0; }
.pfilm video, .package__media video, .package__media img { display: block; width: 100%; height: auto; background: #000; }
.pfilm figcaption { margin-top: 0.6rem; color: var(--dim); }
.package__media { margin: 1.6rem 0 0; }

/* THE WORK, PLAYED -- the front page's excerpt (facility.py work_player): one
   video, both channels upright side by side in its own frame (image left, text
   right), so nothing has to keep them in step. A FRAME (above). Its width is
   held so the 9:8 picture stays on one screen; its caption says which stretch
   of the edit it is. The whole edit, on YouTube, is the .player under it. */
.excerpt { max-width: min(64rem, calc((100svh - 9rem) * 9 / 8)); margin: 0 auto; }
.excerpt__frame { background: #000; }
.excerpt__frame video { display: block; width: 100%; height: auto; aspect-ratio: 9 / 8; background: #000; }
.excerpt__cap { display: flex; flex-wrap: wrap; justify-content: space-between; gap: .3rem 1.2rem;
  margin-top: .7rem; font-size: var(--t-micro); color: var(--dim); }
.excerpt__k { color: var(--lum-max); flex-basis: 100%; }
.excerpt__meta { margin: .5rem 0 0; color: var(--dim); font-size: var(--t-micro); }
.excerpt + .player { max-width: 64rem; margin: calc(var(--gap) * 2) auto 0; }

/* a link that leaves (the drive, or the site) says so, as the drive's footer does
   (its label is LABEL, above) */
.usb-out__k { white-space: nowrap; color: var(--dim); margin-left: 0.15rem; }
