/* The landing page. llamay's own, and nobody else's.
   ---------------------------------------------------------------------------
   This file replaces assets/luminary.css, which was TemplateMo 621 "Luminary"
   adapted -- 72 of the landing page's 92 class names came from it, its licence
   asks for a credit in the footer, and that credit had been removed. Nothing of
   it remains here, so nothing is owed.

   Two ideas hold the page together.

   The first is quantization. llamay's whole technical claim is running a large
   model in few bits: Q4_K_M, Q5, Q8. Dithering and posterisation are that same
   operation applied to an image -- what you do when you have finite levels to
   represent something continuous. So the artwork on this page is not a picture
   of the product, it is the product's own arithmetic, run on light. The bands
   are real: an SVG feComponentTransfer with type="discrete" and four, sixteen
   or sixty-four steps.

   The second is that sovereignty is physical. A rented model is an abstraction
   on somebody else's computer; this one is an object on yours. So the surfaces
   here are printed rather than glassy -- halftone, paper grain, a hard edge and
   an honest shadow -- and nothing floats or glows.

   Type: Fraunces for display (a variable serif; opsz lets one file carry a 96px
   headline and a 12px eyebrow without either looking like the other scaled),
   Inter for reading, JetBrains Mono for anything the machine said. All four are
   served from this origin -- see assets/fonts/ -- because _headers sends
   `style-src 'self'` and a stylesheet on fonts.googleapis.com is refused.

   No inline styles anywhere: the same policy drops them, and scripts/e2e/
   policy_allows_the_page.py now fails the build if one appears. */

/* --- the palette ---------------------------------------------------------
   Warm throughout. The accent is #b45309 / #eba14a, which is the pair already
   shared by site.css, Studio and the macOS app -- the one real cross-surface
   brand colour, and not something to invent a second time here. */
:root {
  --ink: #0c0b0a;          /* near-black, warm -- the ground */
  --ink-2: #141210;
  --ink-3: #1d1a17;
  --bone: #f2efe6;         /* the paper, and the type on dark */
  --bone-2: #b9b2a5;
  --bone-3: #9b9487;       /* 6.2:1 on ink-2; #837c70 was 4.5:1, too faint at 11-12px */
  --line: rgba(242, 239, 230, .13);
  --line-2: rgba(242, 239, 230, .07);
  --amber: #eba14a;
  --amber-deep: #b45309;
  --amber-ink: #1a1206;

  --wrap: 1180px;
  --gutter: clamp(20px, 5vw, 64px);

  /* A firm ease. Things arrive and stop; nothing drifts or bounces. */
  --ease: cubic-bezier(.2, .7, .2, 1);
  --slow: cubic-bezier(.16, 1, .3, 1);

  /* One light, upper-left, warm -- and it never moves. Every shadow on the
     page is cast by it, which is the whole reason the surfaces read as objects
     on a table rather than rectangles on a screen. A light that animates
     destroys that in one frame, so it is a constant, not a variable.

     The shadow colour is brown, never black. A neutral shadow over a warm
     ground is what makes "warm dark" pages look grimy. */
  --light: #fff4e8;
  --shadow: 50 28 12;

  /* Alpha falls as blur grows and the near shadow keeps a negative spread, so
     the object sits on the surface instead of hovering over it. */
  --lift: 0 1px 2px rgb(var(--shadow) / .18),
          0 3px 6px -1px rgb(var(--shadow) / .15),
          0 10px 20px -4px rgb(var(--shadow) / .12),
          0 24px 48px -12px rgb(var(--shadow) / .10);

  /* Anything dithered steps rather than eases. A bitmap cross-fading through
     sub-pixel opacity is the clearest tell of cheap pixel work; eight steps to
     match the eight-cell tile. */
  --ease-step: steps(8, end);

  
  --display: Fraunces, "Instrument Serif", Georgia, serif;
  --sans: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }
figure { margin: 0; }

/* No smooth-scroll. A product whose argument is that it does not intercept
   what you type has no business intercepting how you scroll: the wheel should
   feel exactly like the operating system's. Anchors are handled by
   scroll-margin-top instead, which moves the landing point without taking the
   gesture. */
html { -webkit-text-size-adjust: 100%; }
[id] { scroll-margin-top: 92px; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font: 400 17px/1.6 var(--sans);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* The paper grain. One tiled SVG turbulence, very quiet -- enough that a flat
   field is not flat, not enough to read as texture. */
body::before {
  content: "";
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  opacity: .28;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}

/* The weave: a 2px tile, four 1px squares -- black, silver, gold, bone.
 *
 * One `conic-gradient` does the whole thing. Turning at exact right angles
 * from the tile's centre puts every colour boundary on a whole pixel, so the
 * squares are square: a checker built from diagonal stops, or from a tile at
 * any size the device pixel ratio does not divide, resolves into moire the
 * moment somebody opens it on a laptop. Four hard stops, no interpolation,
 * nothing to alias.
 *
 * One pixel per square is the floor -- there is nothing smaller a screen can
 * draw -- and on a 2x display the browser resolves the tile at the device
 * pixel, so it lands as a true dither rather than a blurred one.
 *
 * `fixed` is doing real work and is not a style choice. A 2px pattern that
 * scrolls with the page redraws its entire field every frame one pixel over,
 * which is the shimmer that makes fine texture unreadable and unpleasant.
 * Pinned to the viewport it is geometrically still while the content moves
 * over it, so it reads as the surface the page is printed on.
 *
 * The opacity and the four colours together are the whole design, and the
 * first attempt got both wrong in the same direction. Full-strength bone and
 * gold at .09 average out to a warm light grey, and a warm light grey laid
 * over a warm near-black does not read as texture on black -- it reads as
 * brown. The ground has to stay near-black, so the weave is mixed dark: its
 * four squares average around #4b463c rather than #a29580, which is what keeps
 * the page black while still having a metal in it.
 *
 * At .055 it is a tooth you notice on a large flat area and never notice
 * behind a paragraph -- which is the point, since everything on this site is
 * read on top of it. Push it much past .08 and the gold starts to win, body
 * text loses contrast, and the field browns again.
 *
 * It sits above the grain and below the content: two layers, because the grain
 * is irregular and this is exact, and the interference between them is what
 * stops the field reading as either plain noise or a printed pattern.
 */
body::after {
  content: "";
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  opacity: .055;
  background-image: conic-gradient(
    from 90deg at 50% 50%,
    #cfcabc 0deg 90deg,     /* bone   */
    #9d7128 90deg 180deg,   /* gold   */
    #000000 180deg 270deg,  /* black  */
    #6f737a 270deg 360deg   /* silver */
  );
  background-size: 2px 2px;
}

/* Both layers off where somebody has asked for less. A fine repeating pattern
   is a known trigger, and this one covers the viewport. */
@media (prefers-reduced-motion: reduce) {
  body::after { opacity: .05; }
}

body > * { position: relative; z-index: 1; }

a { color: inherit; }

.wrap { width: min(var(--wrap), 100%); margin-inline: auto; padding-inline: var(--gutter); }

/* --- type ---------------------------------------------------------------- */
h1, h2, h3 { margin: 0; font-family: var(--display); font-weight: 600; letter-spacing: -.018em; }

/* opsz is why this is one typeface and not three. At display sizes Fraunces
   thins its hairlines and tightens its joins; at caption sizes it opens them
   back up so the same face is still legible at 12px. */
h1 {
  font-size: clamp(46px, 8.2vw, 104px);
  line-height: .96;
  font-variation-settings: "opsz" 144, "SOFT" 20, "WONK" 1;
}
h2 {
  font-size: clamp(32px, 4.6vw, 54px);
  line-height: 1.04;
  font-variation-settings: "opsz" 90, "SOFT" 25, "WONK" 1;
}
h3 {
  font-size: 21px; line-height: 1.25; letter-spacing: -.01em;
  font-variation-settings: "opsz" 30, "SOFT" 40, "WONK" 0;
}

.em { color: var(--amber); font-style: italic; font-variation-settings: "opsz" 144, "SOFT" 60, "WONK" 1; }

/* The machine's voice: anything llamay printed, measured or was configured
   with. Never used for prose. */
.mono, .stat-label, .fine {
  font-family: var(--mono);
  font-variation-settings: normal;
}

.lead { font-size: clamp(18px, 1.5vw, 21px); line-height: 1.55; color: var(--bone-2); margin: 0; max-width: 60ch; }
.body { font-size: 17px; line-height: 1.65; color: var(--bone-2); margin: 0; max-width: 62ch; }
.fine { font-size: 12px; letter-spacing: .04em; color: var(--bone-3); }

/* --- buttons ------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: 10px;
  font: 500 14px/1 var(--mono); letter-spacing: .04em;
  padding: 16px 24px; border-radius: 2px; text-decoration: none;
  border: 1px solid var(--line); color: var(--bone);
  transition: background-color .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease);
}
.btn:hover { border-color: var(--bone-3); background: rgba(242,239,230,.04); }
.btn--go {
  background: var(--amber); color: var(--amber-ink); border-color: var(--amber); font-weight: 600;
  box-shadow: inset 0 1px 0 rgb(255 244 232 / .38), var(--lift);
}
.btn--go:hover { background: #f4b063; border-color: #f4b063; color: var(--amber-ink); }
.btn__k { opacity: .55; }

/* --- nav ----------------------------------------------------------------- */
.nav {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 18px var(--gutter);
  background: linear-gradient(var(--ink) 55%, color-mix(in srgb, var(--ink) 72%, transparent));
  backdrop-filter: blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color .25s var(--ease);
}
.nav.is-past { border-bottom-color: var(--line-2); }
.nav__brand { display: inline-flex; align-items: center; gap: 11px; text-decoration: none; font: 500 17px/1 var(--sans); letter-spacing: -.01em; }
.nav__brand svg { width: 24px; height: 24px; color: var(--amber); }
.nav__links { display: flex; gap: 30px; list-style: none; margin: 0; padding: 0; }
.nav__links a { font: 500 13px/1 var(--mono); letter-spacing: .05em; color: var(--bone-2); text-decoration: none; transition: color .16s var(--ease); }
.nav__links a:hover { color: var(--bone); }
.nav__cta { font: 600 13px/1 var(--mono); letter-spacing: .05em; padding: 12px 18px; border-radius: 2px; background: var(--amber); color: var(--amber-ink); text-decoration: none; }
.nav__burger { display: none; width: 40px; height: 40px; background: none; border: 1px solid var(--line); border-radius: 2px; color: var(--bone); cursor: pointer; padding: 0; }
.nav__burger span { display: block; width: 16px; height: 1px; background: currentColor; margin: 4px auto; transition: transform .2s var(--ease), opacity .2s var(--ease); }
.nav.is-open .nav__burger span:nth-child(1) { transform: translateY(2.5px) rotate(45deg); }
.nav.is-open .nav__burger span:nth-child(2) { opacity: 0; }
.nav.is-open .nav__burger span:nth-child(3) { transform: translateY(-2.5px) rotate(-45deg); }

.menu { display: none; }

/* --- hero ----------------------------------------------------------------
   Left-aligned and asymmetric, against an object. The centred-everything hero
   is what every other page in this category does, and it makes the words and
   the picture compete for the same axis. */
.hero { padding: clamp(60px, 11vh, 130px) 0 clamp(70px, 12vh, 140px); }
.hero__grid { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: clamp(34px, 6vw, 90px); align-items: center; }
.hero h1 { margin-bottom: 26px; }
.hero-sub { font-size: clamp(18px, 1.5vw, 21px); line-height: 1.55; color: var(--bone-2); margin: 0 0 36px; max-width: 60ch; }
.hero-ctas { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 30px; }

/* The object: the shell field, quantized, with its bit-depth labelled. It
   resolves one step on load and then holds -- a demonstration, not a loop. */
.plate { position: relative; aspect-ratio: 1; border: 1px solid var(--line); overflow: hidden; background: var(--ink-2); box-shadow: var(--lift); }
.plate__f { position: absolute; inset: 0; }
.plate__grid {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background-image: linear-gradient(var(--line-2) 1px, transparent 1px), linear-gradient(90deg, var(--line-2) 1px, transparent 1px);
  background-size: 48px 48px;
}

/* --- sections ------------------------------------------------------------ */
/* 128px top and bottom meant 256px of empty band between every two sections,
   and with the figures doing the explaining there is nothing in that band to
   read. 88px is still generous and gives back a screenful over the page. */
.section { padding: clamp(52px, 6.5vw, 88px) 0; border-top: 1px solid var(--line-2); }
.section__head { max-width: 68ch; margin-bottom: clamp(26px, 3.2vw, 44px); }
.section__head h2 { margin-bottom: 18px; }

.cols { display: grid; gap: clamp(20px, 2.4vw, 32px); }
.cols--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cols--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cols--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* A tile is a printed card: hard corners, a real border, no glass. */
.tile {
  border: 1px solid var(--line); padding: 30px; background: var(--ink-2);
  box-shadow: 0 1px 2px rgb(var(--shadow) / .14), 0 4px 10px -3px rgb(var(--shadow) / .10);
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.tile:hover { border-color: rgba(242,239,230,.2); box-shadow: var(--lift); }
.tile h3 { margin-bottom: 12px; }
.tile p { margin: 0; color: var(--bone-2); font-size: 15.5px; line-height: 1.6; }
.tile__n { font: 500 11px/1 var(--mono); letter-spacing: .14em; color: var(--amber); display: block; margin-bottom: 20px; }

/* --- numbers ------------------------------------------------------------- */
.stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 24px; }
.stat__v { font-family: var(--display); font-variation-settings: "opsz" 90, "SOFT" 20, "WONK" 0; font-size: clamp(34px, 4vw, 52px); line-height: 1; color: var(--amber); }
.stat-label { display: block; font-size: 11px; letter-spacing: .13em; text-transform: uppercase; color: var(--bone-3); margin-top: 12px; }

/* --- faq ----------------------------------------------------------------- */
.faq { border-top: 1px solid var(--line-2); }
.faq__q { width: 100%; text-align: left; background: none; border: 0; border-bottom: 1px solid var(--line-2); color: var(--bone); padding: 26px 40px 26px 0; position: relative; cursor: pointer; font: 500 18px/1.35 var(--display); font-variation-settings: "opsz" 40, "SOFT" 30, "WONK" 0; letter-spacing: -.01em; }
.faq__q::after { content: "+"; position: absolute; right: 6px; top: 50%; transform: translateY(-50%); font: 400 20px/1 var(--mono); color: var(--amber); transition: transform .22s var(--ease); }
.faq__q[aria-expanded="true"]::after { transform: translateY(-50%) rotate(45deg); }
.faq__a { display: grid; grid-template-rows: 0fr; visibility: hidden; transition: grid-template-rows .28s var(--ease), visibility 0s linear .28s; border-bottom: 1px solid var(--line-2); }
.faq__a[data-open="1"] { grid-template-rows: 1fr; visibility: visible; transition: grid-template-rows .28s var(--ease), visibility 0s; }
.faq__a > div { overflow: hidden; }
.faq__a p { margin: 0; padding: 0 0 26px; color: var(--bone-2); font-size: 16px; line-height: 1.65; max-width: 70ch; }

/* --- closer and footer --------------------------------------------------- */
.closer { text-align: center; padding: clamp(60px, 8vw, 104px) 0; border-top: 1px solid var(--line-2); }
.closer h2 { margin-bottom: 20px; }
.closer .lead { margin-inline: auto; }
.closer__ctas { display: flex; justify-content: center; flex-wrap: wrap; gap: 12px; margin-top: 34px; }

.foot { border-top: 1px solid var(--line-2); padding: 54px 0 40px; }
.foot__grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 30px; margin-bottom: 44px; }
.foot__label { font: 500 11px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--bone-3); margin: 0 0 16px; }
.foot__grid a { display: block; font-size: 14px; color: var(--bone-2); text-decoration: none; margin-bottom: 10px; transition: color .16s var(--ease); }
.foot__grid a:hover { color: var(--bone); }
.foot__bar { display: flex; flex-wrap: wrap; gap: 12px 26px; justify-content: space-between; align-items: center; padding-top: 26px; border-top: 1px solid var(--line-2); }

/* The one address on the home page, in the bar under the columns.
   It is a link and not a line of fine print, so it is the bar's one item that
   answers to a pointer: the envelope warms with it, and the rule under the
   address is the only thing that moves, which is enough to say "this is
   clickable" without making the strip look like a button.
   `currentColor` on the stroke is what keeps the two halves one object -- the
   icon has no colour of its own to fall out of step with the text's. */
.foot__mail { display: inline-flex; align-items: center; gap: 9px; font: 500 12.5px/1 var(--mono); letter-spacing: .04em; color: var(--bone-2); text-decoration: none; transition: color .16s var(--ease); }
.foot__mail-i { width: 16px; height: 12px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; opacity: .7; transition: opacity .16s var(--ease); }
.foot__mail:hover { color: var(--amber); text-decoration: underline; text-underline-offset: 4px; }
.foot__mail:hover .foot__mail-i { opacity: 1; }

.mt-l { margin-top: 24px; }
.mt-xl { margin-top: 40px; }
/* A centred section centres its heading block too. `.section__head` is capped
   at 68ch so a headline never runs the full width of a 1180px page, and
   without an auto margin that cap sits hard left -- so the words centred
   inside a left-aligned box while the figure below them centred in the whole
   one, and the two were visibly off from each other. */
.center { text-align: center; }
.center .section__head { margin-inline: auto; }
.center .lead, .center .body, .center .moat__note { margin-inline: auto; }

/* --- arrival -------------------------------------------------------------
   Content is never parked invisible waiting for a script. The page is legible
   with no JS at all; only once landing.js has added `js` to <html> -- which it
   can only do if it is running, and therefore able to take it back off -- does
   anything start hidden. site.css makes the same promise for the same reason. */
/* Driven by the scroll itself, in CSS, with no observer and no script. A
   browser that does not support view() timelines simply shows the content --
   the fallback is "visible", not "invisible", which is the whole point.

   The earlier version of this added a class from JS and then hid everything
   the class matched. It animated correctly for anyone scrolling and left the
   page blank for everyone else: a printer, a reader whose script failed, a
   crawler, and -- how it was caught -- a full-page screenshot. Content that is
   only visible if a script keeps a promise is content you have already lost. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .up {
      animation: up-in linear both;
      animation-timeline: view();
      animation-range: entry 4% entry 46%;
    }
    @keyframes up-in {
      from { opacity: 0; transform: translateY(14px); }
      to { opacity: 1; transform: none; }
    }
  }
}

/* --- narrower ------------------------------------------------------------ */
@media (max-width: 1000px) {
  .hero__grid { grid-template-columns: 1fr; gap: 44px; }
  .plate { max-width: 460px; }
  .cols--4, .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .integrations { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .nav__links, .nav__cta { display: none; }
  .nav__burger { display: block; }
  .menu {
    display: block; position: fixed; inset: 64px 0 0; z-index: 39;
    background: var(--ink); padding: 30px var(--gutter);
    transform: translateY(-12px); opacity: 0; pointer-events: none;
    /* Closed is invisible, and has to be unreachable too: opacity alone left
       all eight links in the tab order, so a keyboard walked through a menu
       nobody could see. visibility waits for the fade before it applies. */
    visibility: hidden;
    transition: opacity .2s var(--ease), transform .2s var(--ease), visibility 0s linear .2s;
  }
  .menu.is-open { opacity: 1; transform: none; pointer-events: auto; visibility: visible; transition-delay: 0s; }
  .menu a { display: block; padding: 17px 0; border-bottom: 1px solid var(--line-2); font: 500 16px/1 var(--mono); letter-spacing: .04em; color: var(--bone); text-decoration: none; }
  .cols--2, .cols--3, .cols--4, .stats { grid-template-columns: 1fr; }
  .qstrip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .integrations { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .foot__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- still --------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .up { opacity: 1; transform: none; transition: none; }
  .faq__a { transition: none; }
  * { transition: none !important; animation: none !important; }
}

/* --- /contact/ -----------------------------------------------------------
 *
 * The contact page is on this stylesheet and not on site.css, and that is the
 * second attempt. The first put it on the docs shell, where it was legible and
 * completely wrong: a page reached from the home page's footer that does not
 * look like the home page reads as somebody else's site, and "is this actually
 * llamay" is the last question a contact form should raise.
 *
 * Self-contained below, with its own media query. The form controls borrow
 * nothing and are borrowed from by nothing -- there is no other form on this
 * stylesheet, and coupling these rules to a future one would mean the next
 * form's change is silently this one's.
 */
.hero--plain { padding: clamp(46px, 8vh, 96px) 0 clamp(20px, 3vh, 40px); }
.section--top { border-top: 0; padding-top: clamp(24px, 3vw, 40px); }

.cgrid { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, .85fr); gap: clamp(36px, 6vw, 88px); align-items: start; }

/* Two fields on one line where both are short. A column of eight full-width
   boxes reads as a long form whatever it actually asks for, and how long a
   form looks is what decides whether it gets filled in. */
.cform__pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 20px; }
.cform__row { margin-bottom: 22px; }
.cform label {
  display: block; margin-bottom: 8px;
  font: 500 11px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase;
  color: var(--bone-3);
}
/* A dot, not an asterisk: an asterisk is announced as "star" and promises a
   footnote that is not there. `required` on the field is what actually tells
   anybody assistive, and this is only for the eye. */
.cform .req { color: var(--amber); }

.cform input,
.cform select,
.cform textarea {
  width: 100%; box-sizing: border-box;
  font: 400 15px/1.5 var(--sans);
  color: var(--bone); background: var(--ink-2);
  border: 1px solid var(--line); border-radius: 10px;
  padding: 11px 13px;
  transition: border-color .16s var(--ease), background .16s var(--ease);
}
.cform textarea { min-height: 176px; resize: vertical; }
.cform input::placeholder,
.cform textarea::placeholder { color: var(--bone-3); opacity: .75; }
.cform input:hover,
.cform select:hover,
.cform textarea:hover { border-color: var(--line); background: var(--ink-3); }
.cform input:focus-visible,
.cform select:focus-visible,
.cform textarea:focus-visible { outline: 2px solid var(--amber); outline-offset: 1px; border-color: transparent; background: var(--ink-3); }
/* The native arrow is drawn by the platform in the platform's colours, which
   on a dark field is a light grey wedge on light grey. Replaced with one that
   inherits, and the padding keeps the text clear of it. */
.cform select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23837c70' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 13px center;
  padding-right: 34px;
}
.cform option { background: var(--ink-2); color: var(--bone); }

/* The honeypot. Off-screen rather than `display: none`: the simpler bots skip
   what is not displayed and fill what merely cannot be seen, which is the
   entire point of the field. `aria-hidden` on the wrapper and `tabindex="-1"`
   on the input keep it away from a keyboard and a screen reader both, so
   nothing that is not a bot ever reaches it. */
.cform__pot { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.cform__foot { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 22px; margin-top: 30px; }
.cform__note { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--bone-2); max-width: 46ch; }
.cform__note--ok { color: var(--amber); }
.cform__note--warn { color: #e98b7a; }
.cform__note code { font: 400 12px/1 var(--mono); color: var(--bone); }
.cform__legal { margin-top: 22px; max-width: 54ch; }
.cform button[disabled] { opacity: .5; cursor: default; }

.caside__label { font: 500 11px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--bone-3); margin: 0 0 18px; }
.caside__label--gap { margin-top: 42px; }
.addr { list-style: none; margin: 0; padding: 0; }
.addr li { padding: 13px 0; border-top: 1px solid var(--line-2); }
.addr li:first-child { border-top: 0; padding-top: 0; }
.addr a { display: block; font: 400 13px/1.4 var(--mono); color: var(--bone); text-decoration: none; transition: color .16s var(--ease); }
.addr a:hover { color: var(--amber); }
.addr span { display: block; margin-top: 4px; font-size: 12.5px; color: var(--bone-3); }

/* --- /verify/ ------------------------------------------------------------
   The same two-column shape as /contact/, with the form wider: the thing
   pasted here is a 320-character token, and a narrow box turns one line into
   six and makes a correct licence look malformed. */
.vgrid { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, .8fr); gap: clamp(36px, 6vw, 88px); align-items: start; }

/* The answer. Bordered on the left and coloured by outcome, because this is a
   page somebody scrolls to after scanning and the verdict has to be findable
   at a glance rather than read for. */
.vout { margin-top: 28px; padding: 18px 20px; border-radius: 12px; border: 1px solid var(--line); border-left-width: 3px; background: var(--ink-2); }
.vout--ok { border-left-color: var(--amber); }
.vout--warn { border-left-color: #e0a33c; }
.vout--bad { border-left-color: #e98b7a; }
.vout__h { margin: 0; font: 600 16px/1.3 var(--display); }
.vout--ok .vout__h { color: var(--amber); }
.vout--bad .vout__h { color: #e98b7a; }
.vout__d { margin: 8px 0 0; font-size: 14px; line-height: 1.55; color: var(--bone-2); }

/* The claims, as a definition list because that is what they are. Two columns
   so a label and its value stay on one line at any width that allows it. */
.vfacts { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 7px 16px; margin: 16px 0 0; }
.vfacts dt { font: 500 11px/1.5 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--bone-3); }
.vfacts dd { margin: 0; font-size: 13.5px; color: var(--bone); overflow-wrap: anywhere; }

@media (max-width: 900px) {
  .cgrid, .vgrid { grid-template-columns: minmax(0, 1fr); gap: 48px; }
  .vfacts { grid-template-columns: minmax(0, 1fr); gap: 2px 0; }
  .vfacts dd { margin-bottom: 8px; }
}
@media (max-width: 560px) {
  .cform__pair { grid-template-columns: 1fr; gap: 0; }
}

/* ===========================================================================
   THE MOAT, DRAWN
   ---------------------------------------------------------------------------
   Every other local runtime treats a context as a buffer that dies with the
   process: close the program and the model has to read your whole conversation
   again before it can say anything. llamay's context is an addressable object
   -- /v1/contexts, /v1/contexts/restore -- that forks, snapshots to a file and
   restores on another machine.

   That is the one claim on this page a competitor cannot copy this quarter,
   so it gets a picture rather than a paragraph. Each cell is a page of
   attention state. A fork shares its parent's pages rather than copying them,
   which is why it is instant and nearly free; only a page that is written to
   is ever cloned.
   =========================================================================== */
.moat { display: grid; gap: 30px; }
.moat__rail { display: grid; gap: 14px; }

.pages { display: flex; gap: 4px; align-items: center; }
.page {
  width: 26px; height: 34px; border: 1px solid var(--line);
  background: var(--ink-3); border-radius: 1px;
}
.page--on { background: var(--amber-deep); border-color: var(--amber-deep); }
.page--new { background: var(--amber); border-color: var(--amber); }
.page--ghost { opacity: .32; }

.rowlab {
  font: 500 11px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase;
  color: var(--bone-3); min-width: 128px;
}
.rowlab b { color: var(--amber); font-weight: 500; }
.moat__row { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }

/* The branch bracket: a hairline that leaves the parent and turns down into
   the fork, so the two rows read as one lineage rather than two lists. */
.branch { width: 22px; align-self: stretch; border-left: 1px solid var(--line);
          border-bottom: 1px solid var(--line); margin-left: 12px; }

.moat__note { font: 400 14px/1.55 var(--sans); color: var(--bone-2); margin: 0; max-width: 56ch; }
.moat__note b { color: var(--bone); font-weight: 500; }

/* Against: what everybody else does. Deliberately drawn in the dead grey of
   .page, with nothing amber in it, because there is nothing to keep. */
.versus { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; background: var(--line); border: 1px solid var(--line); }
.versus > div { background: var(--ink-2); padding: 26px 24px; }
.versus h3 { margin-bottom: 14px; }
.versus p { margin: 0 0 16px; color: var(--bone-2); font-size: 15px; line-height: 1.6; }
.versus--them h3 { color: var(--bone-3); }
@media (max-width: 760px) { .versus { grid-template-columns: 1fr; } }

/* --- the conch, drawn ----------------------------------------------------
   pathLength="1" restates the whole contour as length one, so a dash of 1 and
   an offset of 1 hide it and an offset of 0 completes it -- independent of the
   path's real length, which is in the tens of thousands of user units. */
.conch { width: 100%; height: auto; display: block; color: var(--amber); }
.conch path { fill: none; stroke: currentColor; stroke-width: 13; stroke-linecap: round; stroke-linejoin: round; }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .conch path { stroke-dasharray: 1; stroke-dashoffset: 1; animation: conch-draw 2.8s cubic-bezier(.16, 1, .3, 1) .15s forwards; }
    @keyframes conch-draw { to { stroke-dashoffset: 0; } }
  }
}

/* --- the engine, as a datasheet ------------------------------------------
   Hairline-ruled rows, label left, value hard right, tabular figures. A free
   engine decorated like a $99/seat product undermines itself; a spec sheet
   says "this was measured" in a way a card with a gradient border cannot. */
.spec { border-top: 1px solid var(--line); }
.spec__row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 16px; align-items: baseline;
  padding: 15px 0; border-bottom: 1px solid var(--line-2);
}
.spec__k { font: 500 11.5px/1.4 var(--mono); letter-spacing: .13em; text-transform: uppercase; color: var(--bone-3); }
.spec__v { font: 400 15px/1.4 var(--sans); color: var(--bone); text-align: right; font-variant-numeric: tabular-nums; }
.spec__v b { color: var(--amber); font-weight: 500; }
.spec__v .mono { font-size: 13.5px; }

/* --- memory, and where it lives ------------------------------------------ */
.mem { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 2px; background: var(--line); border: 1px solid var(--line); }
.mem > div { background: var(--ink-2); padding: 28px 26px; }
.fact {
  display: flex; gap: 11px; align-items: flex-start;
  padding: 11px 0; border-bottom: 1px solid var(--line-2);
  font-size: 14.5px; color: var(--bone-2); line-height: 1.5;
}
.fact:last-child { border-bottom: 0; }
.fact::before {
  content: ""; flex: none; width: 6px; height: 6px; margin-top: 7px;
  background: var(--amber); border-radius: 1px;
}
.where { display: grid; gap: 10px; }
.where__i {
  display: flex; justify-content: space-between; gap: 14px; align-items: baseline;
  padding: 12px 14px; border: 1px solid var(--line); background: var(--ink);
  font: 500 12.5px/1 var(--mono); letter-spacing: .05em; color: var(--bone-2);
}
.where__i i { font-style: normal; color: var(--bone-3); font-size: 11px; letter-spacing: .1em; }
@media (max-width: 760px) { .mem { grid-template-columns: 1fr; } }

/* The model grid sits in a half-width column here, so five across becomes
   three and the names stay on one line. */

/* A datasheet row is label-left / value-right only while there is room for
   both. In a half-width column the value ran back under its own label -- the
   grid had `auto` for the value track, which does not shrink. Inside a
   two-column block the row stacks instead: label above, value below, both
   left. Same information, no collision. */
.cols--2 .spec__row {
  grid-template-columns: 1fr;
  gap: 5px;
  padding: 13px 0;
}
.cols--2 .spec__v { text-align: left; }


/* --- the conch turns ----------------------------------------------------
   docs/PRODUCT.md's motion doctrine says where that holds and where it does
   not: in the app the mark only breathes while a reply streams, because there
   a moving mark is a status light. A marketing page has no such signal to
   protect, so here the shell draws itself once and then turns, very slowly.
   210s is slow enough that it reads as drift rather than as rotation. */
@media (prefers-reduced-motion: no-preference) {
  .conch { animation: spin 210s linear infinite; transform-origin: 50% 50%; }
  @keyframes spin { to { transform: rotate(360deg); } }
}

/* --- the FAQ, grouped and closed ----------------------------------------
   Forty questions on screen at once is a wall, and a wall is read as "this
   product is complicated". Closed, it is seven lines: somebody looking for
   what it costs opens one group and never sees the ones about GPUs.

   The group headers are buttons, not headings with a script attached, so they
   take focus and answer Enter and Space without being told to. */
.faqgroup { border-bottom: 1px solid var(--line-2); }
.faqgroup:first-of-type { border-top: 1px solid var(--line); }

.faqgroup__h {
  width: 100%; text-align: left; background: none; border: 0; cursor: pointer;
  display: flex; align-items: baseline; gap: 14px;
  padding: 22px 40px 22px 0; position: relative;
  font: 500 12.5px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase;
  color: var(--bone); transition: color .16s var(--ease);
}
.faqgroup__h:hover { color: var(--amber); }
.faqgroup__h::after {
  content: "+"; position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  font: 400 19px/1 var(--mono); color: var(--amber);
  transition: transform .22s var(--ease);
}
.faqgroup__h[aria-expanded="true"] { color: var(--amber); }
.faqgroup__h[aria-expanded="true"]::after { transform: translateY(-50%) rotate(45deg); }
.faqgroup__n {
  font-size: 11px; letter-spacing: .08em; color: var(--bone-3);
  border: 1px solid var(--line); border-radius: 999px; padding: 3px 8px;
}

/* The same 0fr -> 1fr grid the answers use, so a group opens to the height of
   whatever is in it without anybody measuring it in JavaScript. */
.faqgroup__body { display: grid; grid-template-rows: 1fr; transition: grid-template-rows .3s var(--ease); }
.js .faqgroup__body { grid-template-rows: 0fr; visibility: hidden; transition: grid-template-rows .3s var(--ease), visibility 0s linear .3s; }
.js .faqgroup__body[data-open="1"] { grid-template-rows: 1fr; visibility: visible; transition: grid-template-rows .3s var(--ease), visibility 0s; }
.faqgroup__body > div { overflow: hidden; }
.faqgroup__body .faq__q { padding-left: 0; font-size: 17px; }
.faqgroup__body .faq__q:first-of-type { border-top: 1px solid var(--line-2); }
.faqgroup__body > div > :last-child { margin-bottom: 18px; }

.faq__a p + p { margin-top: 14px; }
.faq__a .mono { font-size: .92em; }
.faq__a a { color: var(--amber); }

/* --- the film, and the story it tells ------------------------------------
   The homepage carries the 60-second film and then says what the film says,
   in the same order: six problems, the turn, six answers, how to start, the
   five words the film ends on, who it is for, and where it runs. The copy
   follows the film's script so the two never disagree.

   The mood of a section is the film's: a problem is lit warm, an answer is
   lit cool. Here that is a tint on the section rather than a light that
   moves -- the page's one light is fixed, upper-left, and stays that way.

   Every drawing is inline SVG with its geometry and colour as presentation
   attributes, so it is a picture even if this file never arrives. What this
   file adds is only motion, and all of it stops for prefers-reduced-motion. */
.eyebrow {
  margin: 0 0 18px;
  font: 500 11.5px/1.3 var(--mono); letter-spacing: .18em; text-transform: uppercase;
  color: var(--amber);
}
.eyebrow--warn { color: #e98b7a; }
.eyebrow--ok { color: #4db6a4; }
.hero .eyebrow { margin-bottom: 22px; }
.hero-ctas .btn svg { flex: none; }

.section--film { border-top: 0; padding-top: 0; }
.film {
  position: relative; aspect-ratio: 16 / 9; overflow: hidden;
  border: 1px solid var(--line); border-radius: 10px; background: #0b0a09;
  box-shadow: var(--lift);
}
.film video { display: block; width: 100%; height: 100%; object-fit: cover; background: #0b0a09; }
.film__play {
  position: absolute; inset: 0; display: flex; align-items: flex-end; justify-content: center;
  padding-bottom: 15%; /* under the poster's wordmark, not on top of it */
  background: linear-gradient(180deg, rgb(12 11 10 / 0) 45%, rgb(12 11 10 / .6));
  border: 0; cursor: pointer; color: var(--bone); font: 500 14px/1 var(--mono); letter-spacing: .05em;
}
.film__play span {
  display: inline-flex; align-items: center; gap: 14px;
  padding: 12px 22px 12px 12px; border-radius: 999px;
  background: rgb(20 18 16 / .82); border: 1px solid var(--line);
  transition: transform .2s var(--ease), border-color .2s var(--ease);
}
.film__play:hover span, .film__play:focus-visible span { transform: scale(1.04); border-color: var(--amber); }
.film__play:focus-visible { outline: 2px solid var(--amber); outline-offset: -4px; }
.film__play i { width: 40px; height: 40px; border-radius: 50%; background: var(--amber); display: grid; place-items: center; }
.film__play i::before { content: ""; margin-left: 4px; border-left: 13px solid var(--amber-ink); border-top: 8px solid transparent; border-bottom: 8px solid transparent; }
.film[data-playing] .film__play { display: none; }
/* The overlay is a button only the script can answer, so without the script
   it is not drawn and the video's own controls are what somebody gets. */
html:not(.js) .film__play { display: none; }
.film__cap { margin: 16px 0 0; text-align: center; font: 400 12.5px/1.5 var(--mono); letter-spacing: .04em; color: var(--bone-3); }

/* A heading block that is itself centred, in a section that is not. */
.section__head.center { margin-inline: auto; }
.section__head.center .lead { margin-inline: auto; }

.section--mood[data-mood="warm"] {
  background:
    radial-gradient(70% 55% at 50% 0%, rgb(233 139 122 / .10), transparent 70%),
    linear-gradient(180deg, rgb(70 26 20 / .22), transparent 60%);
}
.section--mood[data-mood="cool"] {
  background:
    radial-gradient(70% 55% at 50% 0%, rgb(77 182 164 / .10), transparent 70%),
    linear-gradient(180deg, rgb(16 52 46 / .24), transparent 60%);
}

.cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(16px, 2vw, 24px); }
.card {
  display: flex; flex-direction: column; overflow: hidden;
  border: 1px solid var(--line); background: var(--ink-2); border-radius: 4px;
  box-shadow: 0 1px 2px rgb(var(--shadow) / .14), 0 4px 10px -3px rgb(var(--shadow) / .10);
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.card:hover { border-color: rgba(242,239,230,.2); box-shadow: var(--lift); }
.card__art { aspect-ratio: 16 / 9; background: #0f0e0c; border-bottom: 1px solid var(--line-2); }
.card__art svg { display: block; width: 100%; height: 100%; }
.card__body { display: flex; flex-direction: column; flex: 1; padding: 20px 22px 24px; }
.card .kw { margin: 0 0 10px; font: 500 10.5px/1.3 var(--mono); letter-spacing: .18em; text-transform: uppercase; color: #e98b7a; }
.card--ok .kw { color: #4db6a4; }
.card h3 { margin-bottom: 10px; font-size: 20px; }
.card p { margin: 0; color: var(--bone-2); font-size: 15px; line-height: 1.6; }
.card .mono { font-size: .88em; color: var(--bone); }
.card .more {
  margin-top: auto; padding-top: 16px; align-self: flex-start;
  font: 500 12px/1 var(--mono); letter-spacing: .05em; color: var(--amber); text-decoration: none;
}
.card .more::after { content: " \2192"; }
.card .more:hover { text-decoration: underline; text-underline-offset: 4px; }

.values { margin-top: clamp(34px, 4vw, 52px); text-align: center; }
.values__row { margin: 0; display: flex; flex-wrap: wrap; justify-content: center; align-items: baseline; gap: 6px 16px; font-family: var(--display); font-size: clamp(22px, 2.6vw, 32px); font-variation-settings: "opsz" 72, "SOFT" 40, "WONK" 0; }
.values__row a { color: var(--bone); text-decoration: none; transition: color .16s var(--ease); }
.values__row a:hover { color: var(--amber); }
.values__row span { color: var(--amber); }
.values__note { margin: 12px 0 0; font: 400 12.5px/1.5 var(--mono); letter-spacing: .04em; color: var(--bone-3); }
.values__note a { color: var(--amber); }

.caps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 clamp(24px, 4vw, 56px); border-top: 1px solid var(--line-2); }
.caps li { display: grid; grid-template-columns: minmax(0, 13em) minmax(0, 1fr); gap: 6px 18px; padding: 18px 0; border-bottom: 1px solid var(--line-2); }
.caps b { font: 600 14px/1.45 var(--mono); letter-spacing: .02em; color: var(--bone); }
.caps a { text-decoration: none; }
.caps a b { color: var(--amber); }
.caps a:hover b { text-decoration: underline; text-underline-offset: 4px; }
.caps li > span { color: var(--bone-2); font-size: 15px; line-height: 1.55; }
.caps .mono { font-size: .88em; color: var(--bone); }

@media (max-width: 1000px) {
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .caps { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .cards { grid-template-columns: 1fr; }
  .caps li { grid-template-columns: 1fr; }
  .film__play { padding-bottom: 6%; }
  .values__row { font-size: 19px; gap: 4px 9px; }
  .film__play span { padding: 7px 14px 7px 7px; gap: 10px; font-size: 12px; }
  .film__play i { width: 28px; height: 28px; }
  .film__play i::before { margin-left: 3px; border-left-width: 10px; border-top-width: 6px; border-bottom-width: 6px; }
}

/* Named rather than counted: an nth-child rule counted an empty <li> that a
   removed link left behind, and the gap it held open was the uneven space
   after "Why llamay". The spacing is each link's own padding rather than the
   list's gap, so a link that steps out takes its space with it and leaves no
   empty item holding a gap open. Below 940px the three figures' links step
   out; they are one scroll apart, and all of them are still in the menu. */
.nav__links { gap: 0; }
.nav__links a { display: block; padding: 12px 15px; white-space: nowrap; }
@media (min-width: 761px) and (max-width: 1180px) {
  .nav__links a { padding-inline: 10px; font-size: 12.5px; letter-spacing: .03em; }
}
@media (min-width: 761px) and (max-width: 940px) {
  .nav__links a:is([href="#system"], [href="#sectors"], [href="#platforms"]) { display: none; }
  .nav__links a { padding-inline: 13px; }
}

/* --- steps: a command in a card --------------------------------------- */
.card--step .kw { color: var(--amber); }
.card .cmd {
  display: block; margin-top: 12px; padding: 9px 11px; overflow-wrap: anywhere;
  font: 400 12.5px/1.4 var(--mono); color: var(--bone);
  background: #0f0e0c; border: 1px solid var(--line-2); border-radius: 3px;
}

/* The drawings move, slowly and a little. transform-box makes every
   transform below relative to the shape it is on, not to the SVG's corner. */
.art * { transform-box: fill-box; transform-origin: center; }
@media (prefers-reduced-motion: no-preference) {
  .art--leave .spark { animation: spark 3.6s linear infinite; }
  .art--leave .spark--2 { animation-delay: .9s; }
  .art--leave .spark--3 { animation-delay: 1.8s; }
  .art--leave .spark--4 { animation-delay: 2.7s; }
  @keyframes spark {
    0% { transform: translate(0, 0); opacity: 0; }
    10% { opacity: 1; }
    100% { transform: translate(140px, -44px); opacity: 0; }
  }
  .art--forget .drain { transform-origin: left center; animation: drain 5s var(--ease) infinite; }
  @keyframes drain { 0%, 30% { transform: scaleX(1); } 55%, 80% { transform: scaleX(.02); } 100% { transform: scaleX(1); } }
  .art--forget .power { animation: blink 5s steps(1, end) infinite; }
  @keyframes blink { 0%, 30% { opacity: .35; } 31%, 55% { opacity: 1; } 56%, 100% { opacity: .35; } }
  .art--chain .lens { animation: search 6s ease-in-out infinite; }
  @keyframes search { 0%, 100% { transform: translate(-10px, 0); } 50% { transform: translate(10px, -4px); } }
  .art--cut .screens { animation: dim 4s ease-in-out infinite; }
  @keyframes dim { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
  .art--eye .sweep { transform-box: view-box; transform-origin: 160px 90px; animation: sweep 7s linear infinite; }
  @keyframes sweep { to { transform: rotate(360deg); } }
  .art--spill .chip { animation: paste 5s var(--ease) infinite; }
  @keyframes paste { 0%, 20% { opacity: 0; transform: translate(-80px, -20px); } 45%, 90% { opacity: 1; transform: none; } 100% { opacity: 0; } }

  .art--fort .orbit { transform-box: view-box; transform-origin: 160px 90px; animation: sweep 40s linear infinite; }
  .art--fort .wall { animation: breathe 4s ease-in-out infinite; }
  @keyframes breathe { 0%, 100% { stroke-opacity: 1; } 50% { stroke-opacity: .55; } }
  .art--gem .glow { animation: glow 4s ease-in-out infinite; }
  @keyframes glow { 0%, 100% { transform: scale(.92); opacity: .7; } 50% { transform: scale(1.06); opacity: 1; } }
  .art--ledger .stamp { animation: stamp 6s var(--ease) infinite; }
  .art--ledger .stamp--2 { animation-delay: .4s; }
  .art--ledger .stamp--3 { animation-delay: .8s; }
  .art--ledger .stamp--4 { animation-delay: 1.2s; }
  @keyframes stamp { 0% { transform: scale(1.6); opacity: 0; } 12%, 85% { transform: scale(1); opacity: 1; } 100% { opacity: 0; } }
  .art--light .beam { transform-origin: left center; animation: beam 5s ease-in-out infinite; }
  @keyframes beam { 0%, 100% { opacity: .4; transform: scaleY(.7); } 50% { opacity: 1; transform: scaleY(1.1); } }
  .art--light .lamp { animation: glow 2.5s ease-in-out infinite; }
  .art--door .stopped { animation: halt 4s ease-in-out infinite; }
  @keyframes halt { 0%, 100% { transform: translateX(0); } 40% { transform: translateX(10px); } 55% { transform: translateX(0); } }
  .art--levels .prompt { animation: settle 5s var(--ease) infinite; }
  @keyframes settle { 0% { transform: translateY(-40px); opacity: 0; } 25%, 88% { transform: none; opacity: 1; } 100% { opacity: 0; } }

  .art--install .drop { animation: bob 2.4s ease-in-out infinite; }
  @keyframes bob { 0%, 100% { transform: translateY(-4px); } 50% { transform: translateY(4px); } }
  .art--install .fill { transform-origin: left center; animation: fillup 4.8s var(--ease) infinite; }
  @keyframes fillup { 0% { transform: scaleX(.04); } 70%, 100% { transform: scaleX(1); } }
  .art--pick .pick { animation: breathe 3.2s ease-in-out infinite; }
  .art--use .wire { animation: flow 1.6s linear infinite; }
  @keyframes flow { to { stroke-dashoffset: -18; } }
}
@media (prefers-reduced-motion: reduce) {
  .art * { animation: none !important; }
}

/* --- what it stands for, who it is for, where it runs ---------------------
   Three figures that explain themselves, each one construction from pure
   geometry: a five-petal lotus inside a yantra's gated square for the five
   values, a flower of life around the mark for the six sectors, and the seed of life --
   seven equal circles, llamay at the centre and a platform on each of the
   six through it -- for where it runs.

   Every coordinate and colour is a presentation attribute in the SVG, computed
   rather than drawn, so the figure is whole with this file missing. What is
   here is layout and motion. landing.js adds `is-armed` only to a figure the
   reader has not reached yet, and `is-drawn` once they do, so the construction
   runs in front of them; a figure already on screen, a reader who asked for
   less motion and a page with no script all get it finished. Each figure's
   points are real buttons laid over it; the full list, name and line, is in a
   list a screen reader reads and a page without the script shows. */
.geo { margin: 0 auto; max-width: 540px; }
.geo__stage { position: relative; width: 100%; aspect-ratio: 1; }
.geo__turn { position: absolute; inset: 0; }
/* A turning square is wider than itself at every angle but four. Everything
   drawn sits inside its circle, so clipping to the square loses nothing. */
.geo--flower .geo__stage { overflow: hidden; }
.geo__svg { position: absolute; inset: 0; display: block; width: 100%; height: 100%; overflow: visible; }

.geo__node {
  --hue: var(--amber);
  position: absolute; z-index: 1; width: 48px; height: 48px; margin: 0; padding: 0;
  transform: translate(-50%, -50%);
  background: none; border: 0; border-radius: 50%; color: var(--bone); cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.geo__disc {
  display: grid; place-items: center; width: 100%; height: 100%; border-radius: 50%;
  background: #0f0e0c; border: 1px solid rgba(242,239,230,.24);
  transition: border-color .25s var(--ease), background-color .25s var(--ease), box-shadow .25s var(--ease);
}
.geo__disc svg { display: block; width: 52%; height: 52%; }
.geo__name {
  position: absolute; left: 50%; top: calc(100% + 6px); transform: translateX(-50%);
  padding: 2px 8px; border-radius: 3px; white-space: nowrap;
  background: rgb(12 11 10 / .84);
  font: 500 13.5px/1.3 var(--sans); letter-spacing: .01em; color: var(--bone-2);
  transition: color .25s var(--ease);
}
.geo__node--up .geo__name { top: auto; bottom: calc(100% + 6px); }
.geo__node:hover .geo__disc { border-color: rgba(242,239,230,.5); }
.geo__node[aria-pressed="true"] .geo__disc {
  border-color: var(--hue);
  background: color-mix(in srgb, var(--hue) 20%, #0f0e0c);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--hue) 22%, transparent);
}
.geo__node[aria-pressed="true"] .geo__name { color: var(--hue); }
.geo__node:focus { outline: none; }
.geo__node:focus-visible .geo__disc { outline: 2px solid var(--hue); outline-offset: 4px; }

/* Each value keeps the colour its icon has always had. */
.geo__node--safe { --hue: #40c8b4; }
.geo__node--secure { --hue: #78aaff; }
.geo__node--private { --hue: #aa82ff; }
.geo__node--local { --hue: #ecb056; }
.geo--seed .geo__node--llamay { --hue: #4db6a4; width: 60px; height: 60px; }
.geo--seed .geo__node--llamay .geo__disc svg { width: 62%; height: 62%; }

/* Where each point sits: the figure's own coordinates, as a share of it. */
.geo--lotus .geo__stage { aspect-ratio: 552 / 552; }
.geo--lotus .geo__node--safe { left: 77.91%; top: 40.93%; }
.geo--lotus .geo__node--secure { left: 67.25%; top: 73.74%; }
.geo--lotus .geo__node--private { left: 32.75%; top: 73.74%; }
.geo--lotus .geo__node--local { left: 22.09%; top: 40.93%; }
.geo--lotus .geo__node--sovereign { left: 50%; top: 20.65%; }
.geo--flower .geo__stage { aspect-ratio: 512 / 512; }
.geo--flower .geo__node--defence { left: 50%; top: 19.53%; }
.geo--flower .geo__node--gov { left: 76.39%; top: 34.77%; }
.geo--flower .geo__node--finance { left: 76.39%; top: 65.23%; }
.geo--flower .geo__node--health { left: 50%; top: 80.47%; }
.geo--flower .geo__node--energy { left: 23.61%; top: 65.23%; }
.geo--flower .geo__node--legal { left: 23.61%; top: 34.77%; }
.geo--seed .geo__stage { aspect-ratio: 504 / 504; }
.geo--seed .geo__node--llamay { left: 50%; top: 50%; }
.geo--seed .geo__node--mac { left: 50%; top: 14.29%; }
.geo--seed .geo__node--win { left: 80.93%; top: 32.14%; }
.geo--seed .geo__node--linux { left: 80.93%; top: 67.86%; }
.geo--seed .geo__node--cli { left: 50%; top: 85.71%; }
.geo--seed .geo__node--android { left: 19.07%; top: 67.86%; }
.geo--seed .geo__node--studio { left: 19.07%; top: 32.14%; }
/* The one line, for whichever point is lit. Its height is held so the page
   does not jump as the line changes length. */
.geo__say {
  margin: clamp(18px, 3vw, 30px) auto 0; max-width: 32em; min-height: 5.6em;
  text-align: center; color: var(--bone);
  font-family: var(--display); font-size: clamp(18px, 1.7vw, 22px); line-height: 1.4;
  font-variation-settings: "opsz" 36, "SOFT" 40, "WONK" 0;
}
.geo__saytext { display: block; }
.geo__sayname {
  display: block; margin-bottom: 8px;
  font: 500 11.5px/1.3 var(--mono); letter-spacing: .18em; text-transform: uppercase; color: var(--amber);
  font-variation-settings: normal;
}
.geo__sayline .mono { font-size: .82em; }
.geo__more {
  display: inline-block; margin-top: 10px;
  font: 500 12px/1 var(--mono); letter-spacing: .05em; color: var(--amber); text-decoration: none;
}
.geo__more:hover { text-decoration: underline; text-underline-offset: 4px; }
.geo__vh, .js .geo__list {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}
.geo__list { list-style: none; margin: 26px auto 0; padding: 0; max-width: 40em; color: var(--bone-2); font-size: 15px; line-height: 1.6; }
.geo__list li { padding: 8px 0; border-bottom: 1px solid var(--line-2); }
.geo__list b { color: var(--bone); font-weight: 600; }
/* No script: nothing can light a point, so the list is what is read. */
html:not(.js) .geo__say { display: none; }

.g-hi { opacity: 0; transition: opacity .35s var(--ease); }
.g-hi.is-on { opacity: 1; }

@media (min-width: 761px) {
  .geo__node--r .geo__name { left: calc(100% + 8px); top: 50%; transform: translateY(-50%); }
  .geo__node--l .geo__name { left: auto; right: calc(100% + 8px); top: 50%; transform: translateY(-50%); }
}
@media (max-width: 560px) {
  .geo__node { width: 40px; height: 40px; }
  .geo--seed .geo__node--llamay { width: 50px; height: 50px; }
  .geo__name { top: calc(100% + 4px); padding: 1px 6px; font-size: 12.5px; }
  .geo__node--up .geo__name { bottom: calc(100% + 4px); }
  .geo__say { min-height: 6.2em; }
}

/* The construction. Before: every line undrawn, every point unlit. After:
   drawn in the order a compass and a straightedge would draw it. */
.geo.is-armed .g-draw { stroke-dasharray: 1 1; stroke-dashoffset: 1; }
.geo.is-armed .g-fade, .geo.is-armed .geo__say { opacity: 0; }
.geo.is-armed .geo__node { opacity: 0; scale: .4; }
.geo.is-armed.is-drawn .g-draw { stroke-dashoffset: 0; transition: stroke-dashoffset 1s var(--slow); }
.geo.is-armed.is-drawn .g-fade, .geo.is-armed.is-drawn .geo__say { opacity: 1; transition: opacity .8s var(--ease); }
.geo.is-armed.is-drawn .geo__node { opacity: 1; scale: 1; transition: opacity .5s var(--ease), scale .6s var(--slow); }

/* lotus: the square and its four gates, the two circles, the five petals
   one after another from the top, then the mark at their centre */
.geo--lotus.is-armed.is-drawn .g-o1 { transition-duration: 1.1s; }
.geo--lotus.is-armed.is-drawn .g-o2 { transition-duration: 1s; transition-delay: .8s; }
.geo--lotus.is-armed.is-drawn .g-o3 { transition-duration: 1s; transition-delay: 1s; }
.geo--lotus.is-armed.is-drawn .g-petals .g-draw { transition-duration: .6s; }
.geo--lotus.is-armed.is-drawn .g-petals .g-draw:nth-child(1) { transition-delay: 1.8s; }
.geo--lotus.is-armed.is-drawn .g-petals .g-draw:nth-child(2) { transition-delay: 2.05s; }
.geo--lotus.is-armed.is-drawn .g-petals .g-draw:nth-child(3) { transition-delay: 2.3s; }
.geo--lotus.is-armed.is-drawn .g-petals .g-draw:nth-child(4) { transition-delay: 2.55s; }
.geo--lotus.is-armed.is-drawn .g-petals .g-draw:nth-child(5) { transition-delay: 2.8s; }
.geo--lotus.is-armed.is-drawn .g-mark { transition-delay: 3.1s; }
.geo--lotus.is-armed.is-drawn .geo__node:nth-of-type(1) { transition-delay: 3.3s; }
.geo--lotus.is-armed.is-drawn .geo__node:nth-of-type(2) { transition-delay: 3.42s; }
.geo--lotus.is-armed.is-drawn .geo__node:nth-of-type(3) { transition-delay: 3.54s; }
.geo--lotus.is-armed.is-drawn .geo__node:nth-of-type(4) { transition-delay: 3.66s; }
.geo--lotus.is-armed.is-drawn .geo__node:nth-of-type(5) { transition-delay: 3.78s; }
.geo--lotus.is-armed.is-drawn .geo__say { transition-delay: 3.9s; }

/* flower of life: the bounds, the first circle, the six around it, the
   twelve beyond, then the petals they leave and the mark at their heart */
.geo--flower.is-armed.is-drawn .g-o1 { transition-duration: .9s; }
.geo--flower.is-armed.is-drawn .g-o2 { transition-duration: 1.1s; transition-delay: .1s; }
.geo--flower.is-armed.is-drawn .g-o3 { transition-duration: .8s; transition-delay: .5s; }
.geo--flower.is-armed.is-drawn .g-ring .g-draw { transition-duration: .9s; }
.geo--flower.is-armed.is-drawn .g-ring .g-draw:nth-child(1) { transition-delay: .9s; }
.geo--flower.is-armed.is-drawn .g-ring .g-draw:nth-child(2) { transition-delay: 1.1s; }
.geo--flower.is-armed.is-drawn .g-ring .g-draw:nth-child(3) { transition-delay: 1.3s; }
.geo--flower.is-armed.is-drawn .g-ring .g-draw:nth-child(4) { transition-delay: 1.5s; }
.geo--flower.is-armed.is-drawn .g-ring .g-draw:nth-child(5) { transition-delay: 1.7s; }
.geo--flower.is-armed.is-drawn .g-ring .g-draw:nth-child(6) { transition-delay: 1.9s; }
.geo--flower.is-armed.is-drawn .g-lat .g-draw { transition-duration: .8s; transition-delay: 2.1s; }
.geo--flower.is-armed.is-drawn .g-lat .g-draw:nth-child(n+7) { transition-delay: 2.4s; }
.geo--flower.is-armed.is-drawn .g-mark { transition-delay: 2.6s; }
.geo--flower.is-armed.is-drawn .g-petals { transition-delay: 2.9s; }
.geo--flower.is-armed.is-drawn .geo__node { transition-delay: 3s; }
.geo--flower.is-armed.is-drawn .geo__node:nth-of-type(2) { transition-delay: 3.1s; }
.geo--flower.is-armed.is-drawn .geo__node:nth-of-type(3) { transition-delay: 3.2s; }
.geo--flower.is-armed.is-drawn .geo__node:nth-of-type(4) { transition-delay: 3.3s; }
.geo--flower.is-armed.is-drawn .geo__node:nth-of-type(5) { transition-delay: 3.4s; }
.geo--flower.is-armed.is-drawn .geo__node:nth-of-type(6) { transition-delay: 3.5s; }
.geo--flower.is-armed.is-drawn .geo__say { transition-delay: 3.6s; }

/* seed of life: llamay first, then six circles that each start from it */
.geo--seed.is-armed.is-drawn .g-draw { transition-duration: 1s; }
.geo--seed.is-armed.is-drawn .g-c1 { transition-delay: 0.70s; }
.geo--seed.is-armed.is-drawn .g-c2 { transition-delay: 1.02s; }
.geo--seed.is-armed.is-drawn .g-c3 { transition-delay: 1.34s; }
.geo--seed.is-armed.is-drawn .g-c4 { transition-delay: 1.66s; }
.geo--seed.is-armed.is-drawn .g-c5 { transition-delay: 1.98s; }
.geo--seed.is-armed.is-drawn .g-c6 { transition-delay: 2.30s; }
.geo--seed.is-armed.is-drawn .geo__node:nth-of-type(1) { transition-delay: .6s; }
.geo--seed.is-armed.is-drawn .geo__node:nth-of-type(2) { transition-delay: 1.30s; }
.geo--seed.is-armed.is-drawn .geo__node:nth-of-type(3) { transition-delay: 1.62s; }
.geo--seed.is-armed.is-drawn .geo__node:nth-of-type(4) { transition-delay: 1.94s; }
.geo--seed.is-armed.is-drawn .geo__node:nth-of-type(5) { transition-delay: 2.26s; }
.geo--seed.is-armed.is-drawn .geo__node:nth-of-type(6) { transition-delay: 2.58s; }
.geo--seed.is-armed.is-drawn .geo__node:nth-of-type(7) { transition-delay: 2.90s; }
.geo--seed.is-armed.is-drawn .geo__say { transition-delay: 3.2s; }

/* The flower turns, once every six minutes, and holds still while a hand is
   on it. The points turn back the other way so their names stay upright. */
@media (prefers-reduced-motion: no-preference) {
  .geo--flower .geo__turn { animation: geo-turn 360s linear infinite; }
  .geo--flower .geo__node { animation: geo-unturn 360s linear infinite; }
  .geo--flower:is(:hover, :focus-within) :is(.geo__turn, .geo__node) { animation-play-state: paused; }
  @keyframes geo-turn { to { transform: rotate(360deg); } }
  @keyframes geo-unturn {
    from { transform: translate(-50%, -50%) rotate(0deg); }
    to { transform: translate(-50%, -50%) rotate(-360deg); }
  }
  .geo__saytext.is-new { animation: geo-say .45s var(--ease); }
  @keyframes geo-say { from { opacity: 0; transform: translateY(4px); } }
}

/* --- polish: landing, focus, closing band, small screens -----------------
   An anchored section lands with its eyebrow a fixed distance under the
   sticky nav at every width. The section's own top padding varies with the
   viewport, so the margin is that padding's complement: the band above the
   eyebrow that would otherwise sit behind the nav is scrolled under it. */
:root { --nav-h: 74px; --land: 56px; }
main > section[id], body > section[id], body > header[id], .pair > section[id] {
  scroll-margin-top: calc(var(--nav-h) + var(--land) - clamp(52px, 6.5vw, 88px));
}
#film { scroll-margin-top: calc(var(--nav-h) + 24px); }
#get { scroll-margin-top: var(--nav-h); }

/* One focus ring for everything a keyboard can reach, in the accent. The
   figures' points and the film's overlay keep the rings they already draw. */
a:focus-visible, button:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; border-radius: 2px; }
.faq__q:focus-visible, .faqgroup__h:focus-visible { outline-offset: -2px; }
.btn--go:focus-visible, .nav__cta:focus-visible { outline-color: var(--bone); }

/* The hero says what llamay is in its first clause, in the reading colour. */
.hero-sub b { color: var(--bone); font-weight: 500; }

/* The FAQ is read, not scanned across 1180px: a measure like the answers'. */
#faq .faq { max-width: 860px; margin-inline: auto; }

/* The closing band: the mark, the descriptor, and the two ways in. */
.closer { padding: clamp(64px, 9vw, 120px) 0; background:
  radial-gradient(60% 70% at 50% 100%, rgb(235 161 74 / .09), transparent 70%); }
.closer__band { max-width: 720px; margin-inline: auto; }
.closer__mark { display: inline-grid; place-items: center; width: 76px; height: 76px; margin-bottom: 26px;
  border: 1px solid rgb(235 161 74 / .35); border-radius: 50%; color: var(--amber);
  background: radial-gradient(circle at 35% 30%, rgb(235 161 74 / .12), transparent 70%), var(--ink-2);
  box-shadow: var(--lift); }
.closer__mark svg { width: 44px; height: 44px; }
.closer h2 { margin-bottom: 16px; }
.closer .lead { color: var(--bone); }
.closer__ctas .btn svg { flex: none; }
.closer__more { margin: 22px 0 0; font: 400 13px/1.6 var(--mono); letter-spacing: .03em; color: var(--bone-3); }
.closer__more a { color: var(--amber); text-underline-offset: 4px; }

/* Tap targets: 44px for everything a thumb is meant to hit. */
.nav__burger { width: 44px; height: 44px; }
.card .more { padding-top: 10px; line-height: 34px; }
.geo__more { margin-top: 2px; padding: 12px 10px; line-height: 20px; }

@media (max-width: 1000px) {
  /* The film sits directly under the hero and opens on the same conch; a
     second, full-width drawing of it only pushed the film off the screen. */
  .hero .plate { display: none; }
  .hero { padding-bottom: clamp(44px, 7vh, 72px); }
}
@media (max-width: 760px) {
  :root { --nav-h: 81px; }
  .foot__grid a { margin: 0; padding: 12px 0; line-height: 20px; }
  .foot__label { margin-bottom: 4px; }
}
@media (max-width: 560px) {
  .geo__node { width: 44px; height: 44px; }
}
@media (max-width: 480px) {
  .hero-ctas, .closer__ctas { flex-direction: column; align-items: stretch; }
  .hero-ctas .btn, .closer__ctas .btn { justify-content: center; }
  /* The drawings keep their proportions and shrink into a shorter frame, so
     twelve cards cost a phone less scrolling. */
  .card__art { aspect-ratio: 2 / 1; }
}

/* --- what it stands for, beside who it is for ------------------------------
   On a wide screen the lotus and the flower are one band in two columns: the
   same size, their centres on one line, each with its heading above and its
   line below. The rows are a subgrid, so a heading that wraps to one more line
   in one column moves both figures down together. Narrower, the two sections
   are simply one after the other, as they have always been. */
@media (min-width: 1024px) {
  .pair {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: auto auto;
    column-gap: clamp(32px, 4vw, 72px);
    padding-inline: max(var(--gutter), (100% - var(--wrap)) / 2 + var(--gutter));
    border-top: 1px solid var(--line-2);
    background:
      radial-gradient(70% 55% at 50% 0%, rgb(77 182 164 / .10), transparent 70%),
      linear-gradient(180deg, rgb(16 52 46 / .24), transparent 60%);
  }
  .pair > .section {
    display: grid; grid-row: span 2; grid-template-rows: subgrid; min-width: 0;
    border-top: 0; background: none;
  }
  .pair > .section > .wrap { display: contents; }
  .pair .section__head { max-width: none; align-self: start; }
  .pair h2 { font-size: clamp(28px, 2.6vw, 38px); line-height: 1.1; }
  .pair .geo { width: 100%; max-width: 500px; }
  .pair .geo__say { font-size: clamp(17px, 1.4vw, 20px); }
}

/* Kosa8 Labs and its products in the footer: the mark beside the name, one line. */
a.brandlink { display: flex; align-items: center; gap: 8px; }
a.brandlink img { width: 16px; height: 16px; border-radius: 4px; flex: none; }

/* --- the shell, sounded --------------------------------------------------
   Everything below is the mark's own motion, and nothing else's. The shankha
   is a conch that is blown: it draws itself, its construction is laid out
   underneath it (a golden spiral, which is how a whelk grows, inside the
   Sudarshana's 108 serrations -- scripts/brand/whorl.py), and then it sounds,
   in rings that go out from the eye of the spiral. The wheel turns against the
   shell. Section heads carry the spiral as their seal, and it turns into place
   as they arrive. The light still never moves; only line does.

   All of it is decoration: every keyframe starts from the finished state's
   opposite only inside prefers-reduced-motion: no-preference, so a reader who
   asked for stillness, a printer and a browser without animations all get the
   finished figure. The `still` block at the top of this file stops the rest. */

/* the plate */
.plate { background:
  radial-gradient(58% 58% at 50% 50%, rgb(235 161 74 / .07), transparent 72%), var(--ink-2); }
.whorl { position: absolute; inset: 0; width: 100%; height: 100%; color: var(--amber); }
.whorl .ln, .whorl .ln-t { fill: none; stroke: currentColor; stroke-width: 1.2; opacity: .34; }
.whorl .ln-t { opacity: .5; }
.whorl .ln-s { fill: none; stroke: var(--bone); stroke-width: .8; opacity: .1; stroke-dasharray: .004 .012; }
.whorl .ln-r { fill: none; stroke: var(--bone); stroke-width: .8; opacity: .14; }
.whorl .ln-p { fill: none; stroke: currentColor; stroke-width: 1.6; opacity: .55; stroke-linecap: round; }
.whorl__wheel { transform-box: fill-box; transform-origin: center; }
.whorl__call circle { fill: none; stroke: var(--amber); stroke-width: 1.2; vector-effect: non-scaling-stroke; opacity: 0;
  transform-box: fill-box; transform-origin: center; }
.conch { position: relative; z-index: 1; }
.conch .conch__glint { stroke: var(--light); stroke-width: 16; stroke-dasharray: .03 .97; opacity: 0; }

.plate__caps { position: absolute; inset: 14px; z-index: 2; pointer-events: none; border: 1px solid var(--line-2); }
.plate__cap { position: absolute; padding: 8px 10px; font: 500 10px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--bone-3); }
.plate__cap--tl { top: 0; left: 0; }
.plate__cap--tr { top: 0; right: 0; color: var(--amber); }
.plate__cap--bl { bottom: 0; left: 0; text-transform: none; letter-spacing: .08em; }
.plate__cap--br { bottom: 0; right: 0; }
/* Registration marks at the frame's corners, printed rather than drawn. */
.plate__caps::before {
  content: ""; position: absolute; inset: -4px;
  background:
    linear-gradient(var(--amber), var(--amber)) 0 0 / 9px 1px no-repeat,
    linear-gradient(var(--amber), var(--amber)) 0 0 / 1px 9px no-repeat,
    linear-gradient(var(--amber), var(--amber)) 100% 0 / 9px 1px no-repeat,
    linear-gradient(var(--amber), var(--amber)) 100% 0 / 1px 9px no-repeat,
    linear-gradient(var(--amber), var(--amber)) 0 100% / 9px 1px no-repeat,
    linear-gradient(var(--amber), var(--amber)) 0 100% / 1px 9px no-repeat,
    linear-gradient(var(--amber), var(--amber)) 100% 100% / 9px 1px no-repeat,
    linear-gradient(var(--amber), var(--amber)) 100% 100% / 1px 9px no-repeat;
  opacity: .7;
}

@media (prefers-reduced-motion: no-preference) {
  /* Arrival, once, in reading order: the claim, then the object. */
  .hero .eyebrow, .h1__ln, .hero-sub, .hero-ctas { animation: rise .9s var(--slow) both; }
  .h1__ln { display: inline-block; }
  .hero .eyebrow { animation-delay: .05s; }
  .h1__ln:nth-child(1) { animation-delay: .14s; }
  .h1__ln:nth-child(2) { animation-delay: .28s; }
  .hero-sub { animation-delay: .46s; }
  .hero-ctas { animation-delay: .6s; }
  @keyframes rise { from { opacity: 0; transform: translateY(22px); } to { opacity: 1; transform: none; } }

  .plate { animation: settle 1.2s var(--slow) .1s both; }
  @keyframes settle { from { opacity: 0; transform: scale(.975); } to { opacity: 1; transform: none; } }

  /* The construction lays itself out under the shell, spokes first, then the
     phi rings from the inside out, then the spiral from its eye. */
  .whorl .ln-s { animation: fade .8s var(--ease) .2s both; }
  .whorl .ln-r { stroke-dasharray: 1; stroke-dashoffset: 1; animation: line 1.4s var(--slow) both; }
  .whorl .ln-r:nth-of-type(5) { animation-delay: .3s; }
  .whorl .ln-r:nth-of-type(4) { animation-delay: .42s; }
  .whorl .ln-r:nth-of-type(3) { animation-delay: .54s; }
  .whorl .ln-r:nth-of-type(2) { animation-delay: .66s; }
  .whorl .ln-r:nth-of-type(1) { animation-delay: .78s; }
  .whorl .ln-p { stroke-dasharray: 1; stroke-dashoffset: 1; animation: line 3.2s cubic-bezier(.45, 0, .2, 1) .4s both; }
  @keyframes line { to { stroke-dashoffset: 0; } }
  @keyframes fade { from { opacity: 0; } }

  /* The wheel turns against the shell, and a little faster than it. */
  .whorl__wheel { animation: fade 1.2s var(--ease) both, spin 160s linear infinite reverse; }

  /* And then it sounds: three rings out from the eye, a breath apart. */
  .whorl__call circle { animation: call 7.2s cubic-bezier(.2, .6, .3, 1) infinite; }
  .whorl__call circle:nth-child(1) { animation-delay: 3.4s; }
  .whorl__call circle:nth-child(2) { animation-delay: 5.8s; }
  .whorl__call circle:nth-child(3) { animation-delay: 8.2s; }
  @keyframes call {
    0% { opacity: 0; transform: scale(.14); }
    12% { opacity: .55; }
    100% { opacity: 0; transform: scale(1.18); }
  }

  /* Light running along the drawn line, once the line exists. */
  .conch .conch__glint { animation: glint 11s linear 3.2s infinite; }
  @keyframes glint {
    0% { stroke-dashoffset: 1; opacity: 0; }
    6% { opacity: .9; }
    70% { opacity: .9; }
    80%, 100% { stroke-dashoffset: -.2; opacity: 0; }
  }
}

/* --- the ticker ----------------------------------------------------------
   What it is, in passing, between the object and the film. A strip of type
   with the spiral as its separator. It moves at reading speed and stops for a
   pointer; with motion reduced it is a still row, cut at the edge. */
.ticker {
  position: relative; overflow: hidden; margin-bottom: clamp(40px, 6vw, 76px);
  border-block: 1px solid var(--line-2);
  background: linear-gradient(90deg, rgb(235 161 74 / .04), transparent 30%, transparent 70%, rgb(235 161 74 / .04));
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.ticker__track { display: flex; width: max-content; }
.ticker__list { display: flex; flex: none; margin: 0; padding: 0; list-style: none; }
.ticker__list li {
  display: inline-flex; align-items: center; gap: 22px; padding: 19px 22px 19px 0;
  font: 500 12px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--bone-2); white-space: nowrap;
}
.ticker__list li::before {
  content: ""; flex: none; width: 15px; height: 15px; background: var(--amber);
  -webkit-mask: url("/assets/spiral.svg") center / contain no-repeat;
  mask: url("/assets/spiral.svg") center / contain no-repeat;
}
@media (prefers-reduced-motion: no-preference) {
  .ticker__track { animation: ticker 70s linear infinite; }
  .ticker:hover .ticker__track { animation-play-state: paused; }
  @keyframes ticker { to { transform: translateX(-50%); } }
}

/* --- the seal on every centred head ---------------------------------------
   The spiral, turned into place as the head arrives. */
.section__head.center::before {
  content: ""; display: block; width: 34px; height: 34px; margin: 0 auto 18px;
  background: var(--amber);
  -webkit-mask: url("/assets/spiral.svg") center / contain no-repeat;
  mask: url("/assets/spiral.svg") center / contain no-repeat;
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .section__head.center::before {
      animation: seal linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 70%;
    }
    @keyframes seal {
      from { opacity: 0; transform: rotate(-240deg) scale(.3); }
      to { opacity: 1; transform: none; }
    }
  }
}

/* --- small things that answer a hand --------------------------------------- */
/* The nav's mark turns a quarter-whorl when pointed at. */
.nav__brand svg { transition: transform .7s var(--slow); }
.nav__brand:hover svg { transform: rotate(-28deg) scale(1.06); }

/* How far down the page you are, as one amber hairline under the nav. */
.nav::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: linear-gradient(90deg, var(--amber-deep), var(--amber));
  transform-origin: 0 50%; transform: scaleX(0);
}
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .nav::after { animation: read linear both; animation-timeline: scroll(root); }
    @keyframes read { to { transform: scaleX(1); } }
  }
}

/* Cards lift on the light's axis, and their keyword's colour draws across the
   top edge: rose for what goes wrong, teal for what llamay does. */
.card { position: relative; transition: border-color .18s var(--ease), box-shadow .25s var(--ease), transform .35s var(--slow); }
.card::before {
  content: ""; position: absolute; inset: 0 0 auto; height: 2px; z-index: 1;
  background: #e98b7a; transform: scaleX(0); transform-origin: 0 50%;
  transition: transform .5s var(--slow);
}
.card--ok::before { background: #4db6a4; }
.card:hover { transform: translateY(-4px); }
.card:hover::before { transform: scaleX(1); }
.card__art svg { transition: transform .6s var(--slow); }
.card:hover .card__art svg { transform: scale(1.04); }

/* The primary button: a band of light crosses it once on hover. */
.btn--go, .nav__cta { position: relative; overflow: hidden; }
.btn--go::after, .nav__cta::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 35%, rgb(255 244 232 / .55) 50%, transparent 65%);
  transform: translateX(-120%);
}
.btn--go:hover::after, .nav__cta:hover::after { transform: translateX(120%); transition: transform .7s var(--ease); }
.btn--go:active { transform: translateY(1px); }

/* The closing mark sounds as well -- the same rings as the hero, smaller. */
.closer { position: relative; overflow: hidden; }
.closer::before {
  content: ""; position: absolute; left: 50%; top: 50%; width: min(900px, 140vw); aspect-ratio: 1;
  translate: -50% -50%; pointer-events: none; z-index: 0;
  background: var(--amber); opacity: .045;
  -webkit-mask: url("/assets/spiral.svg") center / contain no-repeat;
  mask: url("/assets/spiral.svg") center / contain no-repeat;
}
.closer > .wrap { position: relative; z-index: 1; }
.closer__mark { position: relative; }
.closer__mark::before, .closer__mark::after {
  content: ""; position: absolute; inset: -1px; border-radius: 50%;
  border: 1px solid var(--amber); opacity: 0; pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .closer::before { animation: spin 240s linear infinite; }
  .closer__mark::before, .closer__mark::after { animation: ring 4.8s cubic-bezier(.2, .6, .3, 1) infinite; }
  .closer__mark::after { animation-delay: 2.4s; }
  @keyframes ring { 0% { opacity: .6; transform: scale(1); } 100% { opacity: 0; transform: scale(2.6); } }
  .closer__mark svg { transition: transform .7s var(--slow); }
  .closer__mark:hover svg { transform: rotate(-28deg); }
}
