/* ═══════════════════════════════════════════════════════════════════════
   /DAVINITY  ·  also written /DIVINITY
   The house style, carried across from Motus.Love and given a mind.

   Da Vinci and divinity in one word: made by hand, and lit from inside.
   Three rules, and everything below is one of them.

   1. NOTHING IS A RECTANGLE AND NOTHING IS A LOZENGE.
      Every corner here is a SQUIRCLE — a superelliptical curve, not an
      arc. The difference is small in a screenshot and enormous in the
      hand: an arc has a visible moment where the straight edge becomes
      the curve, and a superellipse does not. superellipse(2) IS a
      circular arc; every step above hugs tighter. 2.15 is the least
      squircle that still reads as one continuous curve.

   2. NO BUTTON LOOKS LIKE A BUTTON.
      Every action is an ENERGY GATE: a plate with light banked under its
      bottom edge and a hairline that answers the hand. Lit from within
      rather than filled with a colour. It settles when pressed rather
      than depressing, and it never wears a lozenge.

   3. THE LIGHT IS INSIDE THE THING.
      The object is not lit by the room, it is the source. Inner
      top-light for the surface it is made of, inner under-glow for the
      charge it carries, and only the faintest outer bloom — because a
      thing that mostly glows outward is a lamp, and everything in here
      is a body.

   AND ONE STANDING BAN: NO GREY TEXT. Anywhere. Ever. Secondary
   hierarchy comes from size, weight and a tint — never from draining the
   ink out of a sentence. There are no blurred colour blobs behind
   anything either; the ground is a ground.

   MOBILE FIRST. Every rule here is the phone's rule. The four media
   queries at the bottom are the only places a wider screen is mentioned,
   and they only ever add room.
   ═══════════════════════════════════════════════════════════════════════ */

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  /* ── THE CORNER LANGUAGE ── */
  --dv-corner: superellipse(2.15);
  --r-xs: 18px;
  --r-sm: 26px;
  --r: 34px;
  --r-lg: 44px;
  --r-xl: 56px;
  /* what a former 999px now means: CSS's own clamping does the work, so
     a 40px chip comes out fully round and a 300px panel comes out calm */
  --r-max: 30px;

  /* ── THE GROUND ──
     Violet night, the world Motus lives in. Two stops, no blobs. */
  --ground: #07040F;
  --ground-2: #0A0620;
  --surface: rgba(24, 14, 56, 0.72);
  --surface-lit: rgba(32, 19, 72, 0.86);
  --edge: rgba(178, 140, 255, 0.22);
  --edge-lit: rgba(178, 140, 255, 0.52);

  /* ── THE INK ──
     Near-bone, and a tint. Nothing between them. */
  --ink: #F6F4FF;
  --ink-2: #E6E0FF;
  --tint: #C6B8FF;

  /* ── THE THREE FOUNDATIONS ──
     Colour as grammar. Every accent on a section reads from --fnd, so a
     movement is recoloured by one line and nothing can drift out of
     agreement with it.

       LISTEN   blue    still water — the thing under the surface, held
       ALIGN    violet  the night you were already standing in
       ELEVATE  rose    warmth, effort, the thing you are actually doing */
  --fnd: 178, 140, 255;
  --fnd-ink: #D6C6FF;
  --cyan: 122, 240, 255;
  --rose: 255, 111, 174;
  --blue: 143, 207, 255;
  --violet: 178, 140, 255;
  --gold: 232, 196, 107;

  /* ── THE KEY ──
     One note, and every ambient loop is a whole multiple of it. Harmony
     was never shared pitch, it is shared RATIO: loops at 4 and 6 notes
     are a fifth and re-meet every 12, and with 8, 12 and 24 in the room
     the whole thing resolves every 48 notes — a phrase about eighty
     seconds long that nobody notices and everybody feels. */
  --note: 1.7s;
  --n4: 6.8s;
  --n6: 10.2s;
  --n8: 13.6s;
  --n12: 20.4s;
  --n24: 40.8s;

  --ease: cubic-bezier(.22, .84, .3, 1);
  --sans: "Helvetica Neue", Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
}

.f-listen  { --fnd: 143, 207, 255; --fnd-ink: #BFE2FF; }
.f-align   { --fnd: 178, 140, 255; --fnd-ink: #D6C6FF; }
.f-elevate { --fnd: 255, 111, 174; --fnd-ink: #FFC2DD; }

/* ── 1. THE SQUIRCLE LAW ──
   One property, applied to everything, changing nothing that was not
   already curved. An element with no radius is untouched. */
:where(*, *::before, *::after) { corner-shape: var(--dv-corner); }
/* a face is a face */
:where(.face, [class*='portrait'], [class*='-ava']) { corner-shape: superellipse(2); }
/* a divider is a line by definition, and rounding it is a lie */
:where(hr) { corner-shape: round; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}
body {
  min-height: 100%;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  -webkit-tap-highlight-color: transparent;
}

/* ── THE GROUND ITSELF ──
   Two soft vertical stops and a hairline horizon. Fixed, so it does not
   repaint as the page moves, and painted on a pseudo-element so nothing
   in the document has to carry it. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -2;
  background:
    linear-gradient(180deg, #07040F 0%, #0B0626 38%, #0D0730 66%, #07040F 100%);
}

.wrap { width: min(100% - 32px, 1080px); margin-inline: auto; }
.narrow { width: min(100% - 32px, 760px); margin-inline: auto; }
section { padding: 64px 0; }

/* ═══════════════════════════════════════════════════════════════════════
   TYPE — bigger and bolder, because small titles lose people
   ═══════════════════════════════════════════════════════════════════════ */
h1 { font-size: clamp(2.75rem, 7.4vw, 4.5rem); line-height: 1.09; letter-spacing: -0.012em; font-weight: 500; }
h2 { font-size: clamp(1.9rem, 6vw, 3rem); line-height: 1.14; letter-spacing: -0.008em; font-weight: 500; }
h3 { font-size: clamp(1.4rem, 3.2vw, 1.75rem); line-height: 1.26; letter-spacing: normal; font-weight: 500; }
p  { font-size: clamp(1rem, 3.9vw, 1.13rem); }
.lede { font-size: clamp(1.1rem, 4.6vw, 1.4rem); line-height: 1.52; color: var(--ink-2); }
strong { font-weight: 800; color: var(--ink); }

.eyebrow {
  display: inline-block;
  font-size: 0.79rem;
  font-weight: 800;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--fnd-ink);
  margin-bottom: 16px;
}
hr.rule {
  height: 1px; border: 0; margin: 20px 0 24px;
  background: linear-gradient(90deg, rgba(var(--fnd), .8), rgba(var(--fnd), .08) 58%, transparent);
}

/* ═══════════════════════════════════════════════════════════════════════
   2. THE GATE — every action in the product
   Lit from within, banked under the bottom edge, never a lozenge.
   ═══════════════════════════════════════════════════════════════════════ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 15px 24px;
  min-height: 52px;
  border-radius: var(--r-sm);
  font: inherit;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: 0.012em;
  text-decoration: none;
  cursor: pointer;
  color: var(--ink);
  background: linear-gradient(180deg, rgba(255,255,255,.062), rgba(255,255,255,.022));
  border: 1px solid rgba(255,255,255,.12);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.12),
    inset 0 -13px 22px -16px rgba(var(--fnd), .9);
  transition:
    transform 180ms var(--ease),
    box-shadow 220ms var(--ease),
    border-color 220ms var(--ease),
    background 220ms var(--ease);
}
.btn:hover, .btn:focus-visible {
  border-color: rgba(var(--fnd), .46);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.17),
    inset 0 -18px 28px -16px rgba(var(--fnd), 1),
    0 0 46px -26px rgba(var(--fnd), .9);
}
/* THE SETTLE. A uniform press physics across every surface is the one
   thing that makes a hundred different controls feel like one family. */
.btn:active { transform: translateY(1px) scale(0.988); }
.btn:focus-visible { outline: 2px solid rgba(var(--fnd), .9); outline-offset: 3px; }
.btn[disabled] { opacity: .5; pointer-events: none; }

/* the one lit gate on a page — charged, not filled */
.btn-key {
  border-color: rgba(var(--fnd), .52);
  background: linear-gradient(180deg, rgba(var(--fnd), .17), rgba(var(--fnd), .06));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.2),
    inset 0 -20px 30px -16px rgba(var(--fnd), 1),
    0 0 54px -24px rgba(var(--fnd), .95);
}
.btn-sm { min-height: 44px; padding: 11px 16px; font-size: .92rem; border-radius: var(--r-xs); }
.btn-wide { width: 100%; }

/* ═══════════════════════════════════════════════════════════════════════
   3. THE LIGHT IS INSIDE — surfaces
   ═══════════════════════════════════════════════════════════════════════ */
.card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--edge);
  border-radius: var(--r-lg);
  padding: 26px 22px;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.07),
    inset 0 -22px 44px -34px rgba(var(--fnd), .55);
  transition: transform 260ms var(--ease), border-color 260ms var(--ease),
              background 260ms var(--ease), box-shadow 260ms var(--ease);
}
.card:hover, .card:focus-within {
  border-color: rgba(var(--fnd), .42);
  background: var(--surface-lit);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.1),
    inset 0 -28px 52px -34px rgba(var(--fnd), .8);
}

/* ── THE KEYSTONE ──
   One per page, and only one. Light rising from inside the bottom edge
   in the section's own hue. Used twice it means nothing. */
[data-keystone] {
  border-color: rgba(var(--fnd), .34);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.11),
    inset 0 -10px 22px -6px rgba(var(--fnd), .24),
    0 0 48px -22px rgba(var(--fnd), .85);
}
/* THE SILL — a hairline of light along the bottom edge, brightest at the
   centre and gone at the corners, so it reads as emission, not chrome. */
[data-keystone]::after {
  content: '';
  position: absolute;
  left: 14%; right: 14%; bottom: -1px; height: 1px;
  pointer-events: none;
  border-radius: var(--r-max);
  background: linear-gradient(90deg, transparent,
    rgba(var(--fnd), .9) 32%, rgba(var(--fnd), .9) 68%, transparent);
  opacity: .8;
}

/* ═══════════════════════════════════════════════════════════════════════
   FIELDS — a field with square shoulders in a room of squircles is the
   one thing your eye will find
   ═══════════════════════════════════════════════════════════════════════ */
input, textarea, select {
  width: 100%;
  font: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: rgba(8, 4, 20, 0.72);
  border: 1px solid var(--edge);
  border-radius: var(--r-sm);
  padding: 14px 16px;
  transition: border-color 200ms var(--ease), box-shadow 200ms var(--ease);
}
textarea { min-height: 120px; resize: vertical; line-height: 1.5; }
input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: rgba(var(--fnd), .62);
  box-shadow: 0 0 0 3px rgba(var(--fnd), .16), inset 0 -14px 26px -20px rgba(var(--fnd), .8);
}
/* THE GREY BAN REACHES PLACEHOLDERS. A placeholder is not a text node,
   so a contrast sweep never sees it — and it is the invitation to write,
   so it should read like one. */
::placeholder { color: #B3A4E0; opacity: 1; }
label { display: block; font-size: .93rem; font-weight: 700; color: var(--fnd-ink); margin-bottom: 8px; letter-spacing: .02em; }
.field { margin-bottom: 18px; }
.hint { font-size: .9rem; color: var(--ink-2); margin-top: 8px; }

.check { display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px;
  border: 1px solid var(--edge); border-radius: var(--r-sm); background: rgba(8,4,20,.5);
  cursor: pointer; margin-bottom: 12px; transition: border-color 200ms var(--ease); }
.check:hover, .check:focus-within { border-color: rgba(var(--fnd), .5); }
.check input { width: 22px; height: 22px; flex: none; margin-top: 2px; accent-color: rgb(var(--fnd)); padding: 0; }
.check span { font-size: .98rem; }
.check b { display: block; font-weight: 800; margin-bottom: 2px; }

/* ═══════════════════════════════════════════════════════════════════════
   THE BAR — solid, never glass.
   A blurred backdrop on something that moves with a scroll is the most
   expensive thing a phone can be asked to do, and it buys nothing.
   ═══════════════════════════════════════════════════════════════════════ */
/* ════════════════════════════════════════════════════════════════════
   THE BAR — the nine, on every page

   Glass over the page rather than a lid on it, one hairline of cyan
   along its bottom edge, and the nine destinations as the signs the film
   spends thirty seconds teaching. Words where there is room for words,
   signs where there is not.

   NINE WORDS DO NOT FIT ACROSS A PHONE. That is why the old bar scrolled
   sideways and why it was taken out. Nine SIGNS fit with room to spare,
   so the phone gets the same nine destinations the desk gets — the same
   navigation, drawn shorter, rather than a second one that disagrees.
   ════════════════════════════════════════════════════════════════════ */
.bar {
  position: sticky; top: 0; z-index: 40;
  background: rgba(8, 5, 22, 0.86);
  -webkit-backdrop-filter: blur(22px) saturate(1.35);
  backdrop-filter: blur(22px) saturate(1.35);
  border-bottom: 1px solid rgba(var(--cyan), 0.15);
  transition: transform 460ms var(--ease);
}
/* reading pushes it up, reaching brings it back -- see wireBar() */
.bar.tuck { transform: translateY(-100%); }

.bar .wrap {
  width: min(100% - 26px, 1420px);
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0; min-width: 0;
}
/* A THUMB IS ABOUT FORTY-FOUR PIXELS. The owl was a thirty-pixel square
   and it is the way home from every page on the site. The padding buys
   the hit area without moving anything you can see. */
.bar .home { display: inline-flex; align-items: center; gap: 9px; text-decoration: none;
  color: var(--ink); flex: none; padding: 7px 2px; margin: -7px -2px; }
.bar .home img { width: 30px; height: 30px; display: block; }
.bar .home b { font-weight: 800; font-size: .98rem; letter-spacing: -0.01em; display: none; }
.bar .home:focus-visible { outline: 2px solid rgb(var(--cyan)); outline-offset: 3px; border-radius: 12px; }

.smtabs {
  position: relative;
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; justify-content: center;
  gap: 0;
}
.smtabs .tab {
  --sp: 1;
  position: relative;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 9px;
  border-radius: 15px;
  text-decoration: none;
  color: var(--tint);
  font-size: .86rem; font-weight: 700; letter-spacing: .01em;
  white-space: nowrap;
  transition: color 240ms var(--ease), background 240ms var(--ease);
}
/* the word is the first thing to go when the screen is narrow, because
   the sign is the thing that survives being small */
.smtabs .tab span { display: none; }
.smtabs .tab .tab-sign { width: 23px; height: 23px; flex: none; }
.smtabs .tab:hover, .smtabs .tab:focus-visible { color: var(--ink); background: rgba(var(--cyan), .09); }
.smtabs .tab.on { color: var(--ink); }
.smtabs .tab:focus-visible { outline: 2px solid rgb(var(--cyan)); outline-offset: 2px; }
.bar .gate { flex: none; }

/* ── THE RAIL ──
   One line under the tabs: it rests under the page you are on and
   follows the one you are pointing at. A hundred pixels wide and scaled
   to fit, so it moves and resizes on a transform and never on layout. */
.smtabs .rail {
  position: absolute; left: 0; bottom: -9px;
  width: 100px; height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg,
    rgba(var(--cyan), 0), rgb(var(--cyan)) 20%, #D8FAFF 50%, rgb(var(--cyan)) 80%, rgba(var(--cyan), 0));
  box-shadow: 0 0 16px rgba(var(--cyan), .75);
  transform-origin: left center;
  transform: scaleX(0);
  opacity: 0;
  pointer-events: none;
  transition: transform 480ms var(--ease), opacity 320ms var(--ease);
}

@media (prefers-reduced-motion: reduce) {
  .bar, .smtabs .rail, .smtabs .tab { transition-duration: 1ms; }
}

/* ═══════════════════════════════════════════════════════════════════════
   THE FOOT
   ═══════════════════════════════════════════════════════════════════════ */
footer { border-top: 1px solid var(--edge); padding: 34px 0 56px; margin-top: 24px; }
/* the lines, in every footer, in the one hue that is allowed to insist */
.help { padding: 17px 20px; border-radius: var(--r-sm);
  border: 1px solid rgba(255, 111, 174, .36); background: rgba(255, 111, 174, .07); }
.help b { display: block; font-weight: 800; font-size: .95rem; letter-spacing: .04em;
  color: #FFC2DD; margin-bottom: 6px; }
.help span { font-size: .93rem; color: var(--ink-2); }
/* THESE ARE THE MOST IMPORTANT LINKS ON THE SITE and they were twenty
   pixels tall. Somebody reaching for 988 at four in the morning is not
   reaching accurately. Vertical padding on an inline element grows the
   hit area and moves no type at all. */
.help a { color: #FFC2DD; font-weight: 800; text-underline-offset: 3px;
  padding: 13px 6px; }
.lines-strip a, .txt { padding: 11px 4px; }
.help a:hover, .help a:focus-visible { color: var(--ink); }
.foot { display: grid; gap: 22px; }
.foot .links { display: flex; flex-wrap: wrap; gap: 9px; }
.foot .links a {
  text-decoration: none; color: var(--ink); font-size: .9rem; font-weight: 700;
  padding: 9px 14px; border-radius: var(--r-xs);
  border: 1px solid var(--edge); background: rgba(255,255,255,.03);
  transition: border-color 200ms var(--ease);
}
.foot .links a:hover, .foot .links a:focus-visible { border-color: rgba(var(--fnd), .5); }
.foot .by { font-size: .92rem; letter-spacing: .09em; color: var(--ink-2); }
.foot .by span { display: block; font-size: .82rem; letter-spacing: .26em; color: var(--tint); margin-top: 6px; }

/* ═══════════════════════════════════════════════════════════════════════
   ARRIVAL — transform and opacity only, and never load-bearing.
   Content that has to animate in order to be readable is not content:
   if the observer never fires, everything is simply already here.
   ═══════════════════════════════════════════════════════════════════════ */
.rise { opacity: 0; transform: translateY(20px);
  transition: opacity 300ms var(--ease), transform 300ms var(--ease); }
.rise.seen { opacity: 1; transform: none; }

/* ── THE PAGE TURN ──
   The whole point of "seamless": a link inside the site fades the page
   out and the next one fades in, so moving through it feels like one
   object rather than five documents. */
body { animation: page-in 380ms var(--ease) both; }
body.leaving { opacity: 0; transition: opacity 200ms ease; }
/* FADE ONLY. This used to lift the whole document six pixels, and the
   fill mode left `transform: matrix(1,0,0,1,0,0)` sitting on <body>
   afterwards -- which silently made body the containing block for
   every position:fixed element on the site. */
@keyframes page-in { from { opacity: 0 } to { opacity: 1 } }

/* ── THE BREATH ──
   The single ambient motion in the product, on the key. Used only on the
   mark, because a page where several things breathe reads as restless. */
@keyframes breathe {
  0%, 100% { transform: scale(1); filter: drop-shadow(0 0 22px rgba(178,140,255,.32)) }
  50%      { transform: scale(1.028); filter: drop-shadow(0 0 34px rgba(178,140,255,.5)) }
}
.breathes { animation: breathe var(--n8) ease-in-out infinite; }

.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
a.skip { position: absolute; left: -9999px; }
a.skip:focus { left: 14px; top: 14px; z-index: 60; padding: 12px 18px;
  background: rgb(var(--fnd)); color: #10061F; border-radius: var(--r-xs); font-weight: 800; }

/* links in running text: tinted, never grey, never bright blue */
a.txt { color: var(--fnd-ink); text-underline-offset: 4px; text-decoration-thickness: 1px; font-weight: 700; }
a.txt:hover, a.txt:focus-visible { color: var(--ink); }

/* ═══════════════════════════════════════════════════════════════════════
   REDUCED MOTION
   The settle is a physical answer to a press, so it is shortened rather
   than removed: an interface that does not answer the hand reads as
   broken rather than as calm.
   ═══════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .rise { opacity: 1; transform: none; transition: none; }
  .breathes { animation: none; }
  body { animation: none; }
  .btn, .card { transition-duration: 60ms; }
}

/* ═══════════════════════════════════════════════════════════════════════
   AND ONLY NOW, MORE ROOM
   ═══════════════════════════════════════════════════════════════════════ */
@media (min-width: 560px) {
  .bar .home b { display: block; }
  .card { padding: 30px 28px; }
  section { padding: 84px 0; }
  .foot { grid-template-columns: 1fr auto; align-items: center; }
}
@media (min-width: 900px) {
  body { font-size: 18px; }
  .wrap, .narrow { width: min(100% - 56px, 1080px); }
  .narrow { max-width: 820px; }
  section { padding: 108px 0; }
  .card { padding: 34px 32px; }
}
@media (min-width: 1200px) {
  section { padding: 124px 0; }
}

/* ── THE BAR'S OWN TWO SIZES ──
   At 720 there is room for the wordmark and the gate. At 1120 there is
   room for all nine words, which is the point the signs stop having to
   carry the whole navigation on their own. */
@media (min-width: 720px) {
  .bar .home b { display: block; }
  .bar .wrap { gap: 14px; }
}
@media (max-width: 719px) {
  .bar .wrap { gap: 6px; }
  .smtabs { justify-content: space-between; }
  /* one continuous run of tap targets rather than nine small ones with
     dead ground between them */
  /* eleven of them share a phone's width at ~30px each; a 15px radius on
     a 30px tab is a lozenge, so the corner comes down with the width */
  .smtabs .tab { padding: 10px 0; flex: 1 1 0; justify-content: center; border-radius: 11px; }
  .smtabs .tab .tab-sign { width: 24px; height: 24px; }
  /* the gate is in the page and in the foot; the bar is navigation */
  .bar .gate { display: none; }
}
/* 1260, not 1120: at 1180 the nine words plus the mark plus the gate
   come to twenty pixels more than the row, and a bar that overflows
   by twenty pixels is the sideways-scrolling bar all over again */
/* and 1380 now that there are eleven words, not nine */
@media (min-width: 1380px) {
  .smtabs .tab span { display: inline; }
  .smtabs .tab { padding: 8px 13px; font-size: .9rem; }
  .smtabs { gap: 2px; }
}

/* ════════════════════════════════════════════════════════════════════
   THE SWIPE CARD — the name of where you are going, while you go

   One card, shown twice: the page you leave puts it up, the page you
   arrive at takes it down. The sign draws itself both times, so the
   gesture and the arrival are the same movement seen from either end.
   ════════════════════════════════════════════════════════════════════ */
.swipecard {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  /* NO BACKDROP FILTER. It was a full-viewport blur pass underneath a
     94%-opaque layer -- invisible, and paid for on the one frame that
     has to be fast. */
  background: rgba(7, 4, 16, 0.96);
  opacity: 0;
  pointer-events: none;
  transition: opacity 170ms var(--ease);
}
.swipecard.on { opacity: 1; }
.swipecard.landing { transition-duration: 300ms; }

.swipecard-in {
  display: grid;
  justify-items: center;
  gap: 20px;
  transform: translateX(26px);
  transition: transform 320ms var(--ease);
}
.swipecard[data-dir='back'] .swipecard-in { transform: translateX(-26px); }
.swipecard.on .swipecard-in { transform: none; }

.swipecard-sign {
  width: clamp(56px, 15vw, 86px);
  height: clamp(56px, 15vw, 86px);
  color: rgb(var(--cyan));
  filter: drop-shadow(0 0 14px rgba(var(--cyan), .5));
}
.swipecard b {
  font-size: clamp(1.3rem, 6vw, 2rem);
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  text-indent: .16em;
  color: var(--ink);
}

@media (prefers-reduced-motion: reduce) {
  .swipecard, .swipecard-in { transition-duration: 1ms; }
}

/* ── PROMOTED HEADINGS ──
   Four pages went h1 straight to h3, so a reader moving by level was
   told a level existed and handed nothing at it. These are h2 now and
   have to keep the size they had, because the fix was structural and
   the design was already right. */
.ashead { font-size: 1.16rem; line-height: 1.35; letter-spacing: -0.005em; }
@media (min-width: 720px) { .ashead { font-size: 1.24rem; } }


/* ═══════════════════════════════════════════════════════════════════════
   MOVING BETWEEN THE NINE
   ═══════════════════════════════════════════════════════════════════════
   The shelf should feel like one app, not nine documents. The browser
   can do this itself now: the outgoing and incoming pages are captured
   and animated as images, so there is no white flash and nothing has to
   be rebuilt in JavaScript to fake it.

   THE MOVEMENT IS SMALL ON PURPOSE. Three percent and a fade, over a
   quarter of a second. A full-width slide is a phone from 2014; what
   sells this is that the BAR DOES NOT MOVE AT ALL and the rail glides
   along it to the tab you landed on, exactly the way a native app holds
   its chrome still while the content changes underneath.
   ═══════════════════════════════════════════════════════════════════ */
@view-transition { navigation: auto; }

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 240ms;
  animation-timing-function: var(--ease, cubic-bezier(.2, .8, .3, 1));
}

/* THE NAMES ARE ASSIGNED IN site.js, NOT HERE. A view-transition-name
   must be unique in the document, and /navia builds this shelf twice --
   once as the frame and once inside Navia's room. A selector cannot tell
   those apart, so both matched, and Chrome silently skipped every
   transition instead of warning. The code that builds the bar knows
   which one is the frame; the stylesheet only says how it moves. */
::view-transition-group(sm-bar) { animation-duration: 240ms; }
::view-transition-old(sm-bar),
::view-transition-new(sm-bar) { animation: none; opacity: 1; }
/* and the rail travels, because where it lands IS the answer to
   "where am I now" */
::view-transition-group(sm-rail) {
  animation-duration: 300ms;
  animation-timing-function: cubic-bezier(.2, .9, .25, 1);
}

/* direction only when a thumb or an arrow key asked for one; an ordinary
   link click keeps the browser's own cross-fade */
:root[data-nav='next']::view-transition-old(root) { animation-name: sm-go-out-l; }
:root[data-nav='next']::view-transition-new(root) { animation-name: sm-go-in-r; }
:root[data-nav='back']::view-transition-old(root) { animation-name: sm-go-out-r; }
:root[data-nav='back']::view-transition-new(root) { animation-name: sm-go-in-l; }

@keyframes sm-go-out-l { to { opacity: 0; transform: translateX(-3%); } }
@keyframes sm-go-in-r { from { opacity: 0; transform: translateX(4%); } }
@keyframes sm-go-out-r { to { opacity: 0; transform: translateX(3%); } }
@keyframes sm-go-in-l { from { opacity: 0; transform: translateX(-4%); } }

/* ── THE HAIRLINE, WHICH USUALLY NEVER APPEARS ──
   It is built 140ms after a navigation starts, so on a prerendered page
   it is cancelled before it exists. You only ever see it when there is
   genuinely something to wait for, which is the only honest way to show
   somebody that they are waiting. */
.sm-load {
  position: fixed;
  inset: 0 0 auto 0;
  height: 2px;
  z-index: 120;
  pointer-events: none;
  background: linear-gradient(90deg,
    transparent, rgba(var(--cyan), .95) 45%, rgba(var(--cyan), .35) 70%, transparent);
  background-size: 42% 100%;
  background-repeat: no-repeat;
  animation: sm-load 900ms cubic-bezier(.4, 0, .3, 1) infinite;
}
@keyframes sm-load {
  0% { background-position: -45% 0; }
  100% { background-position: 145% 0; }
}

@media (prefers-reduced-motion: reduce) {
  /* asked not to be moved: the pages still swap instantly, they just do
     not travel to get there */
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
  .sm-load { animation: none; background-position: 0 0; }
}


/* ══════════════════════════════════════════════════════════════════════
   QUIET LIGHT · A FLOOR UNDER EVERYTHING READABLE
   ══════════════════════════════════════════════════════════════════════
   THE BAN ON GREY TEXT WAS KEPT, AND THEN BROKEN SIDEWAYS. Every colour
   pair on this site clears 7:1; the lowest is 7.89:1. And then a hundred
   and eight declarations quietly shrank the same sentences below sixteen
   pixels on a phone. Draining the SIZE out of a line hides it exactly as
   well as draining the ink out of it did, and the worst offenders were
   the crisis lines at 14.88px -- the sentences somebody reads at four in
   the morning.

   One floor, stated once, that a page-level override cannot get under.
   Secondary hierarchy comes from weight and from space, which is what it
   was always supposed to come from.
   ══════════════════════════════════════════════════════════════════ */
.card p, .card .is, .card li,
.narrow > p, .lifeline .where,
.help b, .help span,
.foot .links a, .foot p,
label, .btn-sm, .chip { font-size: max(1rem, 1em); }

/* a caption may be a caption, and no smaller than fourteen */
.card .use, .card .why, .src li, .foot .by span, .eyebrow, .tag {
  font-size: max(.875rem, 1em);
  line-height: 1.5;
}

/* the label voice stops shouting: V4 wants these read, not barked */
.eyebrow, .tag, .day, .when, .who {
  font-weight: 500;
  letter-spacing: .08em;
}

/* ── ONE HUE ──
   Four accents rendered on /services alone. Violet is the hue. Rose
   survives in exactly one place -- the crisis block -- because there,
   being a different colour is a different meaning rather than decoration. */
:root { --fnd: 178, 140, 255; }

/* and the chrome stops being a fifth accent: the keyline is light, not colour */
.bar { border-bottom-color: rgba(255, 255, 255, .06); }
.rail { transition-duration: 200ms; }


/* ══════════════════════════════════════════════════════════════════════
   AND THE FLOOR OUTRANKS THE PAGES
   ══════════════════════════════════════════════════════════════════════
   This stylesheet loads before every page's own <style>, so a page-level
   `.99rem` beat the floor above and the floor did nothing at all. These
   carry !important on purpose: a rule whose whole job is to stop us
   hiding a sentence from somebody has to outrank us.
   ══════════════════════════════════════════════════════════════════ */
.card p, .card .is, .card li, .card > div > p,
.narrow > p, .lifeline .where, .where, .hint,
.help b, .help span, .foot p, .foot .links a,
label, .btn-sm, .chip, .n2-act, .plainly, .said span {
  font-size: 1.02rem !important;
  line-height: 1.55;
}

/* a caption may be a caption -- fourteen pixels, and not one less */
.card .use, .card .why, .use, .why, .src, .src li,
.day, .when, .tag, .eyebrow, .who, .foot .by span {
  font-size: .9rem !important;
  line-height: 1.5;
}

/* ── DISPLAY TYPE STOPS SHOUTING ──
   V4 wants it huge and at weight 500. Bolder-is-better is the reflex
   this system retires; size and space carry the hierarchy instead. */
h1, h2, h3, .word, .hash, .ashead, .n, .check b, .bar .home b {
  font-weight: 500 !important;
}

/* ── MOTION INSIDE THE BUDGET ── */
.bar, .rail { transition-duration: 200ms !important; }
body, .room, .said, .plainlys, .lift { transition-duration: 300ms !important; }


/* the last of it: controls and footnotes that were still under the floor */
.rename, .n2-who b, .n2h a, .plainlys button, .plainlys a,
.swipecard b, .foot small, .sig { font-size: 1rem !important; }

/* and the animations, which the transition cap above did not reach --
   .said and .plainlys were arriving over nine hundred milliseconds */
.said, .plainlys, .lift, .rise, .n2h i, body {
  animation-duration: 300ms !important;
  transition-duration: 300ms !important;
}


/* the remainder were unclassed inline spans, which are always running
   text -- and the pasted baseline, which is meant to be read before it
   is copied */
main span:not([class]), main b:not([class]), main a:not([class]),
.says, .city, .plainly { font-size: 1rem !important; }
pre, pre * { font-size: .95rem !important; line-height: 1.6; }
i { animation-duration: 300ms !important; }


/* two unclassed lines in Navia's header sat outside main at 12.5px --
   the smallest text left on the site, and it was hers */
body b:not([class]):not(.bar b), body a:not([class]):not(.bar a) {
  font-size: 1rem !important;
}


/* ══════════════════════════════════════════════════════════════════════
   MIND OVER NOISE
   ══════════════════════════════════════════════════════════════════════
   The picture fills the screen it is given without ever being cropped:
   capped by HEIGHT on a wide screen and by WIDTH on a phone, so the
   framing the song was cut with is the framing anybody sees.
   ══════════════════════════════════════════════════════════════════ */
.songtop { padding: 0 0 8px; }
.songwrap { display: grid; place-items: center; padding: 0 clamp(0px, 2vw, 22px); }
.songbox {
  position: relative;
  width: 100%;
  max-width: calc(82vh * 16 / 9);
  aspect-ratio: 16 / 9;
  overflow: hidden;
  /* the radius has to be a real SHARE of the smaller side, or a wide
     short box reads as a rectangle with the corners filed off */
  border-radius: clamp(28px, 3.4vw, 40px);
  corner-shape: superellipse(2.15);
  border: 1px solid rgba(255, 255, 255, .07);
  background: #06040F;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
}
.songbox iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; }

.songnote {
  margin: 14px auto 0;
  text-align: center;
  color: var(--ink-2);
  font-size: 1rem !important;
  font-weight: 500;
}
.songnote span {
  display: inline-block;
  padding: 9px 16px;
  border-radius: 18px;
  corner-shape: superellipse(2.15);
  border: 1px solid rgba(var(--fnd), .3);
  background: rgba(178, 140, 255, .07);
}

/* THE BAR STYLES ITSELF, IN site.js, NEXT TO THE CODE THAT BUILDS
   IT -- because index.html does not load this stylesheet and the
   bar goes on every page. Only the Story page hero lives here. */



/* ══════════════════════════════════════════════════════════════════════
   THE PLAYER BAR, OUT OF THE WAY
   ══════════════════════════════════════════════════════════════════════
   THREE THINGS IT GOT WRONG.

   `hidden` is implemented as display:none at user-agent priority, so
   `.songmute { display: grid }` beat it and a control the code believed
   was hidden sat on screen, pressable, on six pages. An attribute is not
   a promise unless the stylesheet keeps it.

   It also sat bottom-LEFT, which is exactly where /talk keeps Take your
   words and Clear -- so the song covered the two buttons that let
   somebody carry their words out or delete them. And on the film it was
   underneath the picture's own layers, so it could not be pressed at all.
   ══════════════════════════════════════════════════════════════════ */
.songmute[hidden], .songgate[hidden] { display: none !important; }

/* (the bar's own rules live in site.js -- see dress()) */

/* and a page that scrolls ends ABOVE the bar rather than underneath it */
main { padding-bottom: 92px; }

/* 15.8px, and the floor is sixteen */
.not, .not * { font-size: 1rem !important; }


/* ══════════════════════════════════════════════════════════════════════
   THE SAME MOVE, ON A THUMB
   ══════════════════════════════════════════════════════════════════════
   240ms is right for a mouse and too brisk for a hand. A swipe takes
   longer to make than the animation took to answer it, so the page had
   already changed before the thumb finished moving.

   Slower, further, and with a BEAT: the incoming page is held at its
   first frame for 130ms while the outgoing one is still travelling, so
   you watch the page you were on leave, then the new one arrives. The
   two never crossfade through each other, which is the thing that read
   as cheap.
   ══════════════════════════════════════════════════════════════════ */
@media (pointer: coarse), (max-width: 700px) {
  ::view-transition-old(root) {
    animation-duration: 400ms;
    animation-timing-function: cubic-bezier(.34, 0, .26, 1);
  }
  ::view-transition-new(root) {
    animation-duration: 460ms;
    /* THE BEAT. `backwards` holds the new page at its opening frame
       through the delay, so the gap is empty rather than a crossfade. */
    animation-delay: 130ms;
    animation-fill-mode: backwards;
    animation-timing-function: cubic-bezier(.2, .84, .24, 1);
  }

  /* the chrome stays put; the rail takes its time getting to the new tab */
  ::view-transition-group(sm-bar) { animation-duration: 400ms; }
  ::view-transition-group(sm-rail) {
    animation-duration: 560ms;
    animation-timing-function: cubic-bezier(.2, .92, .22, 1);
  }

  :root[data-nav='next']::view-transition-old(root) { animation-name: sm-out-l-m; }
  :root[data-nav='next']::view-transition-new(root) { animation-name: sm-in-r-m; }
  :root[data-nav='back']::view-transition-old(root) { animation-name: sm-out-r-m; }
  :root[data-nav='back']::view-transition-new(root) { animation-name: sm-in-l-m; }

  /* further than the desktop's 3%, and it settles rather than stopping */
  @keyframes sm-out-l-m { to { opacity: 0; transform: translateX(-10%) scale(.962); } }
  @keyframes sm-in-r-m { from { opacity: 0; transform: translateX(12%) scale(1.035); } }
  @keyframes sm-out-r-m { to { opacity: 0; transform: translateX(10%) scale(.962); } }
  @keyframes sm-in-l-m { from { opacity: 0; transform: translateX(-12%) scale(1.035); } }
}

/* asked not to be moved: still instant, still no travel */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation-delay: 0s !important; }
}


/* the mission, in the footer of every page */
.foot .by .mission { display: block; font-weight: 500; color: var(--ink);
  letter-spacing: .02em; margin-bottom: 6px; font-size: 1rem; }
.mission-line { margin-top: 14px; font-weight: 500; font-size: 1rem;
  letter-spacing: .02em; color: var(--tint); }

/* how many SoundMinds are here right now, under the signature in the foot */
.foot .here { display: block; margin-top: 8px; font-weight: 500; color: var(--fnd-ink); }
.foot .here[hidden] { display: none; }
