/* ==========================================================================
   Auralar.co — the public site.

   The same house style as the calendar, on purpose. Somebody who signs up here
   and opens the app five minutes later should not feel they have moved to a
   different company: the same paper, the same serif, the same hairline rules,
   the same squared corners. A bright rounded page in front of a printed-looking
   calendar is two products wearing one name.

   THE SAME TYPE AS THE APP'S RUSTIC LOOK (css/fonts.css, loaded before this
   file): "Auralar Serif" for headings and the wordmark, "Auralar Sans" for
   reading, IBM Plex Mono for the drawn product's figures. Each face waits for
   nothing (font-display: swap) and its stand-in is the device's own Georgia
   or Arial scaled to the same width, so a slow connection gets the page at
   once and the swap moves nothing.
   ========================================================================== */
/* --------------------------------------------------------------------------
   THE PALETTE IS RUSTIC'S, COPIED EXACTLY.

   Not "similar to" — the same hex values as LOOKS[rustic] in the calendar's
   themes.js, which is the look a new household gets. The light halves already
   agreed; the dark halves did not, and that was the whole of "the site is a
   completely different theme from the app". The site's dark used to be a warm
   brown-black (#16150f paper, #f2efe3 ink) while Rustic dark is a neutral
   charcoal (#191918 / #eeedea), so anybody whose phone is set to dark went
   from a brown marketing page to a grey calendar and saw two products.

   IF THESE EVER DIVERGE AGAIN, themes.js is the original and this is the copy.
   They cannot share a file: the calendar writes its palette onto the root at
   runtime from JavaScript, because a look can be changed; the site has one
   look and must render with JavaScript off.

   The three ways a mode can be decided, in order of who wins:
     1. `data-theme` on <html>  — the visitor pressed the switch in the bar.
     2. prefers-color-scheme    — nobody has pressed it; follow the screen.
     3. the light values below  — neither is available.
   Which is the same order the calendar uses, so pressing the switch here and
   opening the app gives the answer you just asked for.
   -------------------------------------------------------------------------- */
:root {
  --bg:      #f4f1e8;
  --panel:   #faf8f2;
  --panel-2: #efeadb;
  --panel-3: #e6e0cd;
  --line:    #cdc6b1;
  --line-2:  #b5ac92;
  --ink:     #17150f;
  --ink-2:   #57523f;
  --ink-3:   #6a6452;
  --good:    #3d6b40;
  /* Headings, reading, figures — the app's Rustic faces (css/fonts.css),
     each with its metric-matched stand-in and then the system faces. */
  --serif: "Auralar Serif", "Auralar Serif Fallback", "Auralar Serif Fallback 2",
           Georgia, "Iowan Old Style", "Times New Roman", "Nimbus Roman", serif;
  --sans:  "Auralar Sans", "Auralar Sans Fallback", "Auralar Sans Fallback 2",
           "Helvetica Neue", Helvetica, Arial, "Liberation Sans", sans-serif;
  --mono:  "IBM Plex Mono", "Auralar Mono Fallback",
           ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  --shadow: 0 1px 0 rgba(23,21,15,.06), 0 18px 46px -28px rgba(23,21,15,.55);
  /* The people in the drawn product (see "the product, drawn live" below):
     the colours the app gives Ana, Bruno, Clara and Diogo, lifted a step for
     dark paper so they read on it the way they do on light. */
  --p-ana: #3b8ae2; --p-bruno: #4fae52; --p-clara: #e08b2f; --p-diogo: #b556c9;
  --flag: #a8321f;          /* the family goal's marker on the month bar */
  --bezel: #2b2a26;         /* a tablet's or phone's frame */
  --glow: .7;
  /* THE SIDE GUTTER. Never less than 20px, so nothing on a phone touches the
     edge of the glass; it widens with the screen up to 56px. */
  --gut: clamp(20px, 5.6vw, 56px);
  /* THE SPACING SCALE. Every gap on the front page is one of these, so the
     page has one rhythm instead of a dozen nearly-equal ones. It was close to
     twice this between sections (94px of padding either side of a rule) and
     the owner rightly called it empty: a section now ends, a rule, and the
     next one starts a comfortable breath later. --sp-band is the space either
     side of the rule between two sections; the rest step up from 4px.
     Taken down once more (68px a side became 56px) when the owner still
     found the page airy: with a hairline between every section the rule
     already does the separating, and the space only has to let it breathe. */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px;
  --sp-6: 32px; --sp-7: 48px;
  --sp-band: clamp(36px, 5vw, 56px);
  color-scheme: light;
}

/* The dark half, written once and referenced twice — once for the screen that
   asks for it, once for the visitor who asked for it. The `:not([data-theme])`
   guard is what lets the switch win: with an explicit choice on <html>, the
   media query stops applying and rule 1 above holds. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --bg:#191918; --panel:#232322; --panel-2:#2a2a28; --panel-3:#353533;
    --line:#3a3a38; --line-2:#55554f;
    --ink:#eeedea; --ink-2:#b2b0aa; --ink-3:#949189;
    --good:#79bf85;
    --shadow: 0 1px 0 rgba(0,0,0,.4), 0 18px 46px -28px rgba(0,0,0,.9);
    --p-ana:#6ea8ee; --p-bruno:#6cc070; --p-clara:#eba55a; --p-diogo:#c986da;
    --flag:#e0735f; --bezel:#0c0c0b; --glow:.45;
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg:#191918; --panel:#232322; --panel-2:#2a2a28; --panel-3:#353533;
  --line:#3a3a38; --line-2:#55554f;
  --ink:#eeedea; --ink-2:#b2b0aa; --ink-3:#949189;
  --good:#79bf85;
  --shadow: 0 1px 0 rgba(0,0,0,.4), 0 18px 46px -28px rgba(0,0,0,.9);
  --p-ana:#6ea8ee; --p-bruno:#6cc070; --p-clara:#eba55a; --p-diogo:#c986da;
  --flag:#e0735f; --bezel:#0c0c0b; --glow:.45;
  color-scheme: dark;
}
:root[data-theme="light"] { color-scheme: light; }

* { box-sizing: border-box; }
/* The bar is sticky and 64px tall, so a jump to #anything (the tables of
   contents, "See what it does") has to stop that far short or the heading it
   was aiming for lands underneath the bar. 16px more so it does not sit hard
   against it. */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 80px; }
:target { scroll-margin-top: 80px; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: var(--sans); font-size: 17px; line-height: 1.58;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
/* `height: auto` is not optional here. Every picture on this site carries
   width and height attributes so the page does not jump about while it loads,
   and those attributes are a USED height until CSS says otherwise — so
   `max-width: 100%` shrank the width and left the height where it was, and
   every picture was squashed. */
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
/* ONE LINK STYLE. A link inside running text — a paragraph, a list item, a
   table cell, the footer's small print, an email address on Contact — looks
   the same everywhere: the text's own face and size, in ink, with a thin
   underline set a little below the letters that thickens on hover. It used to
   be three styles (typewriter, underlined serif, underlined sans). Navigation
   (the bar, the menu, the footer's link rows) and buttons are not running text
   and keep their own look. :where() so any rule below can still adjust it. */
:where(p, li, td, dd) a:where(:not(.btn)) {
  color: var(--ink);
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .2em;
  text-decoration-color: color-mix(in srgb, currentColor 50%, transparent);
}
:where(p, li, td, dd) a:where(:not(.btn)):hover { text-decoration-thickness: 2px; text-decoration-color: currentColor; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

.wrap { width: min(1120px, 100%); margin: 0 auto; padding-inline: var(--gut); }
.kicker {
  font-family: var(--sans); font-size: 10.5px; font-weight: 600;
  letter-spacing: .24em; text-transform: uppercase; color: var(--ink-3);
}
/* Small caps leave the lower-case letters half the height of a capital, so
   the usual 1.2 line height reads as a blank line between every line of a
   heading. 1.12 closes that up without the capitals touching. */
h1, h2, h3 { font-family: var(--serif); font-weight: 400; font-variant: small-caps; letter-spacing: .04em; margin: 0; line-height: 1.12; text-wrap: balance; }
/* Paragraphs inside a section: one gap between them, none after the last, so
   a section's bottom padding is the only space at its foot. */
:where(.band) p { margin: 0 0 var(--sp-4); }
:where(.band) p:last-child { margin-bottom: 0; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 99;
  background: var(--ink); color: var(--bg); padding: 12px 18px;
}
.skip:focus { left: 0; }

/* --- the bar ------------------------------------------------------------- */
.bar {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
.bar-in { display: flex; align-items: center; gap: 18px; min-height: 64px; }
.mark {
  font-family: var(--serif);
  font-size: 22px; font-variant: small-caps; letter-spacing: .12em;
  text-decoration: none; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 10px;
}
/* The column sits ON the baseline of the small caps rather than centred on
   the line — a capital and a capital letter should stand on the same floor. */
.mark-ic { flex: none; transform: translateY(1px); }
/* THE WORDMARK — AURALAR.co. The name in capitals, then the domain in the
   same serif, lower case, a size down and a shade lighter, sitting on the
   same baseline: one word whose ending is quieter, so ".co" is remembered
   without shouting. `font-variant: normal` because small-caps would turn the
   lower-case "co" into capitals too. */
.wm { display: inline-flex; align-items: baseline; }
.wm-tld {
  font-variant: normal; text-transform: none;
  font-size: .74em; letter-spacing: .03em; color: var(--ink-2);
  margin-left: -.04em;
}
/* --------------------------------------------------------------------------
   The light/dark switch.

   It sits at the left-hand end of the nav, before "What it does", so it reads
   as a property of the page rather than another destination. Two states: it
   shows the page's colours as they are, and one press gives the other ones.
   Choosing the device's own colours forgets the choice, so it follows the
   device again — see site.js.

   Drawn as a sun or a moon with no text — the one you will GET by pressing.
   The label lives in aria-label and title, both rewritten by site.js, so a
   screen reader and a hover both get the whole sentence.
   -------------------------------------------------------------------------- */
.bar-theme {
  margin-left: auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; flex: none;
  padding: 0; background: none; color: var(--ink-2);
  border: 1px solid transparent; border-radius: 999px;
  cursor: pointer;
  transition: color .16s ease, border-color .16s ease, background-color .16s ease;
}
/* `display: inline-flex` above would otherwise beat the `hidden` attribute,
   and with scripting off the button would show and do nothing. */
.bar-theme[hidden] { display: none; }
.bar-theme:hover { color: var(--ink); border-color: var(--line); background: var(--panel-2); }
.bar-theme svg { width: 19px; height: 19px; display: block; }
/* One of the two drawings is shown: the moon while the page is light (press
   for dark), the sun while it is dark (press for light). */
.bar-theme [data-ic] { display: none; }
.bar-theme[data-state="light"] [data-ic="dark"],
.bar-theme[data-state="dark"]  [data-ic="light"] { display: block; }

.bar-in > nav { display: flex; gap: 22px; margin-left: 20px; font-family: var(--sans); font-size: 13.5px; }
.bar-in > nav a { color: var(--ink-2); text-decoration: none; padding: 12px 0; white-space: nowrap; }
.bar-in > nav a:hover, .bar-in > nav a.on { color: var(--ink); }
.bar-cta { display: flex; gap: 10px; margin-left: 22px; }
@media (max-width: 960px) {
  .bar-in > nav { display: none; }
}
/* Five links need the room; "Questions" is also in the footer of every page. */
@media (max-width: 1100px) {
  .bar-in > nav { gap: 18px; margin-left: 12px; }
  .bar-in > nav .nav-q { display: none; }
}
/* NARROW BARS. Everything in the bar has to fit at every width from 320px up
   without anything leaving the screen. Below 600px the gaps close up and
   "Start free" gets smaller; "Sign in" leaves the bar for the menu panel (or,
   with no scripting, the row of plain links under the bar), so the bar is the
   mark, the switch, "Start free" and the menu button. */
@media (max-width: 600px) {
  .bar-in { gap: 8px; }
  .bar-cta { gap: 4px; margin-left: 0; align-items: center; }
  .bar-cta .btn { min-height: 40px; padding: 0 13px; font-size: 15px; }
  .bar-cta .btn:not(.btn-primary) { display: none; }
}
/* The wordmark is wider than the old name by its ".co", so it steps down a
   size before the bar runs out of room. */
@media (max-width: 460px) {
  .bar .mark { font-size: 19px; gap: 8px; letter-spacing: .08em; }
  .bar .mark-ic { width: 26px !important; height: 26px !important; }
}
@media (max-width: 400px) {
  .bar-in { gap: 6px; }
  .bar .mark { font-size: 18px; gap: 7px; letter-spacing: .08em; }
  .bar .mark-ic { width: 26px !important; height: 26px !important; }
  .bar-cta .btn { padding: 0 11px; }
}

/* --- the phone menu (site.js › "The phone menu") --------------------------
   A button at the right-hand end of the bar, from 960px down, where the nav
   above is hidden. It opens a panel that hangs from the bottom edge of the
   bar, over the page, with the links set large enough to hit with a thumb.
   Both start `hidden` and only site.js shows the button; the `[hidden]` rules
   matter because `display` would otherwise beat the attribute. */
.bar-menu {
  display: none; align-items: center; gap: 7px; flex: none;
  min-height: 40px; padding: 0 12px; margin-left: 4px;
  background: var(--panel); color: var(--ink);
  border: 1px solid var(--line-2); border-radius: 3px;
  font: inherit; font-size: 15px; cursor: pointer;
}
.bar-menu svg { width: 18px; height: 18px; display: block; }
.bar-menu:hover, .bar-menu.is-open { background: var(--panel-3); }
.bar-menu[hidden] { display: none !important; }
@media (max-width: 960px) { .bar-menu { display: inline-flex; } }
/* On the narrowest phones the word goes and the three lines stay; the
   button's accessible name is still "Menu", from the text that is only
   visually hidden. */
@media (max-width: 460px) {
  .bar-menu { padding: 0; width: 40px; justify-content: center; margin-left: 0; }
  .bar-menu span {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
  }
}
/* PHONES: both buttons are 44x44 touch targets, same icons. Last, so it wins
   over the sizes above. */
@media (max-width: 600px) {
  .bar-theme { width: 44px; height: 44px; }
  .bar-menu { min-height: 44px; }
}
@media (max-width: 460px) {
  .bar-menu { width: 44px; }
}
.menu-panel {
  position: absolute; left: 0; right: 0; top: 100%;
  background: var(--bg); border-bottom: 1px solid var(--line);
  box-shadow: 0 22px 40px -30px rgba(23,21,15,.55);
  max-height: calc(100dvh - 64px); overflow-y: auto;
}
.menu-panel[hidden] { display: none; }
@media (min-width: 961px) { .menu-panel { display: none !important; } }
.menu-panel nav { display: grid; padding-block: var(--sp-2) var(--sp-5); }
.menu-panel nav > a {
  display: block; padding: 13px 0; font-size: 19px; text-decoration: none; color: var(--ink);
  border-bottom: 1px solid var(--line);
}
.menu-panel nav > a:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .2em; }
.menu-cta { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); margin-top: var(--sp-5); }
/* With no scripting: the same links as a plain row under the bar. */
.menu-plain { display: none; }
@media (max-width: 960px) {
  .menu-plain {
    display: flex; flex-wrap: wrap; gap: 0 18px; padding-block: 0 8px;
    font-family: var(--sans); font-size: 14px;
  }
  .menu-plain a { color: var(--ink-2); padding: 8px 0; }
}

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 18px;
  font-family: var(--sans); font-size: 15.5px;
  border: 1px solid var(--line-2); background: var(--panel); color: var(--ink);
  border-radius: 3px; text-decoration: none; cursor: pointer; white-space: nowrap;
}
.btn:hover { background: var(--panel-3); }
.btn-primary { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.btn-primary:hover { background: var(--ink-2); border-color: var(--ink-2); }
.btn-soon { cursor: default; opacity: .72; }
.btn-soon:hover { background: var(--ink); border-color: var(--ink); }
.soon-note { max-width: 46ch; margin: var(--sp-4) auto 0; text-align: center; color: var(--ink-2); font-size: 15px; line-height: 1.5; }
.btn-lg { min-height: 54px; padding: 0 26px; font-size: 17px; }
.linky {
  background: none; border: 0; padding: 12px 0; cursor: pointer;
  font: inherit; font-family: var(--sans); font-size: 13px; color: var(--ink-2);
  text-decoration: underline; text-underline-offset: 2px;
}
.linky:hover { color: var(--ink); }

/* --- the hero ------------------------------------------------------------ */
.hero { padding-block: clamp(32px, 6vw, 72px) 0; text-align: center; }
.hero .kicker { display: block; margin-bottom: var(--sp-3); line-height: 1.6; font-variant: normal; }
/* Two lines on a desktop, not four: the headline was set so large that it
   took four lines and pushed the picture of the wall below the fold. One break
   after "one wall," keeps the two halves of the sentence on their own lines;
   on a phone each half is free to wrap and is balanced by text-wrap. */
.hero h1 { font-size: clamp(34px, 5.6vw, 64px); line-height: 1.04; letter-spacing: .045em; max-width: 19em; margin-inline: auto; }
.hero p.lede {
  margin: var(--sp-5) auto 0; max-width: 44ch; line-height: 1.5;
  font-size: clamp(17px, 2.2vw, 21px); font-style: italic; color: var(--ink-2);
}
.hero-cta { display: flex; gap: var(--sp-3); justify-content: center; flex-wrap: wrap; margin-top: var(--sp-6); }
.shot { position: relative; margin-top: clamp(32px, 5vw, 56px); isolation: isolate; }
/* A soft wash of the family's colours behind the tablet, kept inside the
   section so it can never widen the page. */
.shot::before {
  content: ""; position: absolute; inset: 8% 0 -6%; z-index: -1; pointer-events: none;
  opacity: var(--glow);
  background:
    radial-gradient(36% 48% at 24% 58%, color-mix(in srgb, var(--p-ana) 24%, transparent), transparent 70%),
    radial-gradient(34% 46% at 76% 44%, color-mix(in srgb, var(--p-diogo) 20%, transparent), transparent 70%),
    radial-gradient(40% 40% at 52% 88%, color-mix(in srgb, var(--p-clara) 18%, transparent), transparent 70%);
}

/* --- bands --------------------------------------------------------------- */
/* padding-BLOCK, never the `padding: X 0` shorthand: these sections are also
   `.wrap`, and the shorthand's 0 wiped out the side gutter, which is why the
   text and pictures ran to the edges of a phone. */
.band { padding-block: var(--sp-band); }
.band + .band { border-top: 1px solid var(--line); }
/* The heading may run to two lines across the page rather than three down a
   narrow column — it was held to 46 characters of BODY text, which at heading
   size is barely four words, and left the right half of every section head
   empty. The paragraph under it keeps a reading measure. */
.band-head { max-width: 760px; }
.band-head h2 { font-size: clamp(26px, 3.6vw, 38px); margin-top: var(--sp-2); }
.band-head p { color: var(--ink-2); font-size: 17.5px; max-width: 54ch; margin-top: var(--sp-3); }

/* The plain "what Auralar is" paragraph: a full reading measure, in ink
   rather than grey, because it is the one paragraph on the page everybody
   should read. */
.band-head p.what-is { color: var(--ink); max-width: 64ch; font-size: 18px; line-height: 1.6; }

/* THREE ROWS, not six boxes. Each row is a heading on the left and its words
   on the right, set at reading size (the boxes were 15.5px grey in a third of
   the page and measured 11 to 12px on the review screens). Ruled apart like
   a newspaper's index, no cards. */
.feats { display: grid; margin-top: var(--sp-6); border-top: 1px solid var(--line); }
.feat { display: grid; gap: var(--sp-2) var(--sp-7); padding-block: var(--sp-5); border-bottom: 1px solid var(--line); }
@media (min-width: 800px) { .feat { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); align-items: baseline; } }
.feat h3 { font-size: clamp(21px, 2.4vw, 25px); display: flex; align-items: center; gap: var(--sp-3); text-wrap: pretty; }
.feat p { margin: 0; color: var(--ink-2); font-size: 17px; line-height: 1.6; max-width: 58ch; }
.feat .ic { color: var(--ink-3); flex: none; display: block; }

.split { display: grid; gap: clamp(24px, 4vw, 56px); align-items: center; }
@media (min-width: 900px) {
  .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); }
  .split.is-flipped > :first-child { order: 2; }
  .split.is-narrow { grid-template-columns: minmax(0, 1fr) 340px; gap: clamp(30px, 5vw, 70px); }
  .split.is-narrow.is-flipped { grid-template-columns: 340px minmax(0, 1fr); }
}
.split h2 { font-size: clamp(24px, 3.2vw, 34px); margin: var(--sp-2) 0 var(--sp-4); }
.split p { color: var(--ink-2); }
.split ul { margin: var(--sp-4) 0 0; padding: 0; list-style: none; display: grid; gap: var(--sp-2); }
.split li { position: relative; padding-left: 26px; color: var(--ink-2); font-size: 16px; line-height: 1.5; }
.split li::before {
  content: ""; position: absolute; left: 4px; top: .62em;
  width: 9px; height: 2px; background: var(--line-2);
}
.frame { min-width: 0; }
.frame.is-phone { width: min(290px, 100%); margin-inline: auto; }

/* --- the tour: the planner, the month and the phone -----------------------
   As markup (no script, or reduced motion) it is three steps, one after the
   other, each with its own picture — ruled apart like the bands they used to
   be. site.js turns it into a pinned stage only when it is allowed to move
   things; see "the tour" there and in the motion block at the end. */
.tour-step + .tour-step {
  margin-top: var(--sp-band); padding-top: var(--sp-band);
  border-top: 1px solid var(--line);
}

/* --- plans --------------------------------------------------------------- */
.plan { margin-top: var(--sp-6); display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
@media (min-width: 820px) { .plan { grid-template-columns: 1fr 1fr; } }
.plan > div { background: var(--panel); padding: var(--sp-6) var(--sp-6) var(--sp-6); }
@media (max-width: 600px) { .plan > div { padding: var(--sp-5) var(--sp-5) var(--sp-6); } }
.plan h3 { font-size: 23px; }
.plan .price { font-family: var(--sans); font-size: 13px; color: var(--ink-3); margin: var(--sp-1) 0 var(--sp-4); }
.plan ul { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--sp-2); }
.plan li { padding-left: 26px; position: relative; font-size: 15.5px; color: var(--ink-2); }
.plan li::before {
  content: ""; position: absolute; left: 2px; top: .3em; width: 13px; height: 7px;
  border-left: 1.6px solid var(--good); border-bottom: 1.6px solid var(--good);
  transform: rotate(-45deg);
}
/* --- what it costs, in figures -------------------------------------------
   The prose version of this box is still in index.php and still styled by the
   two rules at the top — it is what shows before Paddle has been set up, or if
   the figures could not be fetched. Everything below it is the version with
   real numbers in it.

   SET AS A TABLE OF FIGURES, not as three marketing cards. The point being
   made is that one column of numbers goes DOWN, and the way to make a column
   of numbers legible is the way a printed page has always done it: tabular
   figures, right of a label, one per line, with the last one marked. Three
   cards side by side would say "three plans", which is the opposite of what is
   true — it is one plan that gets cheaper. */
.ladder { margin-top: var(--sp-5); padding: var(--sp-5); background: var(--panel-2); border-left: 3px solid var(--ink); }
.ladder p { margin: 0; font-size: 16px; color: var(--ink-2); }
.ladder b { color: var(--ink); }
.ladder h3 { font-size: 19px; margin: 0 0 4px; }
.ladder h3 + .rungs { margin-top: 18px; }
.ladder .rungs + p { margin-top: 18px; }

.rungs { display: grid; gap: 22px 40px; }
@media (min-width: 720px) { .rungs { grid-template-columns: 1fr 1fr; } }

.rung-set .kicker { display: block; margin-bottom: 8px; }
.rung-set ol { margin: 0; padding: 0; list-style: none; display: grid; }
.rung-set li {
  display: flex; align-items: baseline; gap: 12px;
  padding: 7px 0;
  border-bottom: 1px solid var(--line);
}
.rung-set li:last-child { border-bottom: 0; }
.rung-set li b {
  /* Tabular, so the decimal points line up down the column — which is the
     whole reason this is a list of figures and not a sentence. */
  font-variant-numeric: tabular-nums;
  font-size: 20px; min-width: 4.6ch; color: var(--ink);
}
.rung-set li span { font-family: var(--sans); font-size: 12.5px; color: var(--ink-3); }
/* The one they end up on, and stay on. A rule above it rather than a colour:
   the page has no accent to spend here, and "and then it stops" is a line. */
.rung-set li.last b { font-weight: 700; }
.rung-set li.last span { color: var(--ink-2); }

/* One subscription, every household — under the list rather than in the price
   line, where it was making a two-clause sentence out of a price. */
.plan-cov {
  margin: var(--sp-4) 0 0; padding-top: var(--sp-3); border-top: 1px solid var(--line);
  font-family: var(--sans); font-size: 12.5px; color: var(--ink-3);
}

/* --- coming soon: the roadmap, drawn as a line through time ---------------
   Its own section after the price, so it reads as "what is next" and never
   as part of what Premium gets you today.

   THE DRAWING. One stop per quarter, in the order they come (the markup is
   already in that order and already has the empty quarters folded into gap
   stops — see site_roadmap_lanes()). Along the top of the stops runs a line,
   with a dot where each quarter starts and the quarter's name under its dot:
     - the line starts in the quarter we are in, with "Today" standing on it
       at today's place, and is inked solid up to there;
     - quarters to come are the paler rule, with an open dot;
     - a gap stop (quarters with nothing planned) is a dotted stretch, narrow,
       so the distance shows without spending a column on each empty quarter;
     - "Later" has no date, so its stretch is dashed and fades out.
   Under each name hang its cards. Premium is ink, free is the page's one
   green (the colour the plans use for what you get) — on the card's edge, in
   the tag, and once in the key above the line.

   WIDE (900px up): stops side by side, each at least 200px (a gap stop
   104px); more than fit scroll sideways inside their own focusable box,
   never the page. BELOW: the line turns and runs down the left-hand side,
   names and cards to its right; a gap stop shrinks to one line. */
.roadmap { --rm-axis: 2px; --rm-dot: 11px; --rm-y: 11px; }
.roadmap-head { max-width: 760px; }
.roadmap h2 { font-size: clamp(26px, 3.6vw, 38px); }
.roadmap-sub { margin: var(--sp-3) 0 0; color: var(--ink-2); font-size: 17.5px; max-width: 54ch; }

/* The key: two swatches, said once, so a card's edge means something. */
.rm-key {
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-5);
  margin: var(--sp-4) 0 0; padding: 0; list-style: none;
  font-family: var(--sans); font-size: 12.5px; color: var(--ink-2);
}
.rm-key li { display: inline-flex; align-items: center; gap: var(--sp-2); }
.rm-key li::before { content: ""; width: 12px; height: 12px; border-radius: 2px; background: var(--ink); }
.rm-key .rm-key-free::before { background: var(--good); }

.rm-scroll { margin-top: var(--sp-6); min-width: 0; }
.rm-scroll:focus-visible { outline-offset: 6px; }
.rm-track, .rm-items { margin: 0; padding: 0; list-style: none; }
.rm-lane { position: relative; min-width: 0; }

/* The line, one stretch per stop, and the dot where the stop starts. */
.rm-lane::before, .rm-lane::after { content: ""; position: absolute; pointer-events: none; }
.rm-lane::before { background: var(--line-2); }
.rm-lane::after {
  width: var(--rm-dot); height: var(--rm-dot); border-radius: 50%;
  background: var(--bg); border: 2px solid var(--line-2);
}
.rm-lane:not(.is-gap):not(.is-later):not(.has-now)::after { border-color: var(--ink-2); }
.rm-lane.is-later::after { border-style: dashed; }
/* "Today" stands where the first dot would, so that dot is not drawn. */
.rm-lane.has-now::after { display: none; }

.rm-now {
  position: absolute; z-index: 1;
  font-family: var(--sans); font-size: 10.5px; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; line-height: 1; white-space: nowrap;
  padding: 5px 8px 4px; border-radius: 999px;
  background: var(--ink); color: var(--bg);
  box-shadow: 0 0 0 3px var(--bg);
}

.rm-when { display: grid; gap: 2px; margin: 0; font-weight: 400; letter-spacing: 0; }
.rm-q { font-family: var(--serif); font-size: 21px; line-height: 1.1; font-variant: small-caps; letter-spacing: .04em; }
.rm-sub {
  font-family: var(--sans); font-variant: normal; letter-spacing: 0;
  font-size: 12.5px; line-height: 1.35; color: var(--ink-3);
}
.rm-lane.has-now .rm-sub { color: var(--ink-2); }
.rm-lane.is-later .rm-q { color: var(--ink-2); }
/* A gap stop is a stretch of time, not a destination: set small and quiet. */
.rm-lane.is-gap .rm-q {
  font-family: var(--sans); font-variant: normal; letter-spacing: 0;
  font-size: 12.5px; font-weight: 600; color: var(--ink-3);
}
.rm-lane.is-gap .rm-sub { font-style: italic; }
.rm-none { margin: var(--sp-3) 0 0; font-size: 15px; font-style: italic; color: var(--ink-3); }

.rm-items { display: grid; gap: var(--sp-3); margin-top: var(--sp-3); align-content: start; }
.rm-item {
  display: grid; gap: var(--sp-1); min-width: 0; align-content: start;
  padding: var(--sp-3) var(--sp-4);
  background: var(--panel); border: 1px solid var(--line);
  border-left: 3px solid var(--ink);
}
.rm-item.is-free { border-left-color: var(--good); }
.rm-lane.is-later .rm-item { background: transparent; border-style: dashed; border-left-style: solid; }
.roadmap-title { font-size: 16.5px; line-height: 1.3; color: var(--ink); overflow-wrap: anywhere; }
.roadmap-desc { font-size: 14.5px; line-height: 1.45; color: var(--ink-2); overflow-wrap: anywhere; }
.roadmap-tags { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 6px; margin-top: var(--sp-1); }
.roadmap-prem, .roadmap-free, .roadmap-late {
  font-family: var(--sans); font-size: 11.5px; line-height: 1.5;
  padding: 0 8px; border: 1px solid var(--line-2); border-radius: 999px; color: var(--ink-2);
}
.roadmap-prem { background: var(--ink); border-color: var(--ink); color: var(--bg); }
.roadmap-free { border-color: var(--good); color: var(--good); }
.roadmap-late { border-style: dashed; }

/* --- wide: the line runs across, stops side by side ------------------------- */
@media (min-width: 900px) {
  .rm-scroll {
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x proximity; scrollbar-width: thin;
    padding-bottom: var(--sp-2);
  }
  .rm-track { display: flex; }
  .rm-lane {
    flex: 1 1 0; min-width: 184px;
    padding: calc(var(--rm-y) + 22px) var(--sp-5) 0 0;
    scroll-snap-align: start;
  }
  /* The last stop keeps a margin the width of the fade below, so with
     everything in view the fade lies over nothing. */
  .rm-lane:last-child { padding-right: 40px; }
  /* More stops than fit: the right-hand edge fades into the paper, so it
     is plain there is more to the line than is on screen. Sticky inside the
     scrolling box, so it stays at its edge however far it has scrolled. */
  .rm-track::after {
    content: ""; flex: 0 0 40px; margin-left: -40px;
    position: sticky; right: 0; z-index: 2; pointer-events: none;
    background: linear-gradient(to right, color-mix(in srgb, var(--bg) 0%, transparent), var(--bg));
  }
  /* A stop wider than one card (few stops on the line) sets its cards side
     by side rather than stretching one card across half the page. */
  .rm-items { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
  .rm-lane.is-gap { flex: 0 0 112px; min-width: 0; }
  .rm-lane.has-now.is-empty { flex: 0 0 168px; min-width: 0; }
  .rm-lane::before { left: 0; right: 0; top: calc(var(--rm-y) - var(--rm-axis) / 2); height: var(--rm-axis); }
  .rm-lane::after { left: 0; top: calc(var(--rm-y) - var(--rm-dot) / 2); }
  .rm-lane.has-now::before {
    background: linear-gradient(to right, var(--ink) calc(var(--at, 0) * 100%), var(--line-2) 0);
  }
  .rm-lane.is-gap::before {
    background: repeating-linear-gradient(to right, var(--line-2) 0 2px, transparent 2px 6px);
  }
  .rm-lane.is-later::before {
    background: repeating-linear-gradient(to right, var(--line-2) 0 6px, transparent 6px 11px);
    -webkit-mask: linear-gradient(to right, #000 55%, transparent);
            mask: linear-gradient(to right, #000 55%, transparent);
  }
  /* "Today" stands ON the line at today's place, kept inside its stop: at
     the very start of a quarter its left edge is where the dot would be, at
     the very end its right edge is at the stop's end. */
  .rm-now {
    top: var(--rm-y); left: calc(var(--at, 0) * (100% - var(--sp-5)));
    translate: calc(var(--at, 0) * -100%) -50%;
  }
  .rm-lane:last-child .rm-now { left: calc(var(--at, 0) * 100%); }
}

/* --- narrower: the line turns and runs down the left ------------------------ */
@media (max-width: 899px) {
  .rm-track { display: grid; }
  .rm-lane { padding: 0 0 var(--sp-6) 36px; }
  .rm-lane:last-child { padding-bottom: 0; }
  .rm-lane::before { top: 0; bottom: 0; left: calc(var(--rm-y) - var(--rm-axis) / 2); width: var(--rm-axis); }
  .rm-lane:first-child::before { top: var(--rm-y); }
  .rm-lane::after { left: calc(var(--rm-y) - var(--rm-dot) / 2); top: 7px; }
  /* Today's place inside a quarter means nothing on a line whose length is
     set by how much is written beside it, so here "Today" heads the first
     stop, above its name, with the line inked down to it. */
  .rm-lane.has-now { padding-top: 30px; }
  .rm-lane.has-now::before {
    top: var(--rm-y);
    background: linear-gradient(to bottom, var(--ink) 30px, var(--line-2) 0);
  }
  .rm-now { left: 0; top: 0; }
  .rm-lane.is-gap { padding-bottom: var(--sp-5); }
  .rm-lane.is-gap .rm-when { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--sp-2); }
  .rm-lane.is-gap::before {
    background: repeating-linear-gradient(to bottom, var(--line-2) 0 2px, transparent 2px 6px);
  }
  .rm-lane.is-gap::after { top: 4px; }
  .rm-lane.is-later::before {
    background: repeating-linear-gradient(to bottom, var(--line-2) 0 6px, transparent 6px 11px);
    -webkit-mask: linear-gradient(to bottom, #000 60%, transparent);
            mask: linear-gradient(to bottom, #000 60%, transparent);
  }
}
/* A tablet held upright has room for two cards side by side under a stop. */
@media (min-width: 600px) and (max-width: 899px) {
  .rm-items { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
}

/* A quiet aside inside a legal document — "this is also published at …". */
.doc-note { font-family: var(--sans); font-size: 13px; color: var(--ink-3); }

/* The line under the plans: where the figures come from and who takes the
   money. Was a hero-note with an inline style to undo its centring. */
.price-note { margin: var(--sp-4) 0 0; font-family: var(--sans); font-size: 12.5px; line-height: 1.6; color: var(--ink-3); max-width: 92ch; }


/* --- a document ---------------------------------------------------------- */
.doc { padding-block: clamp(36px, 6vw, 72px) clamp(50px, 8vw, 90px); }
.doc h1 { font-size: clamp(30px, 4.5vw, 44px); margin-top: 10px; }
.doc-date { font-family: var(--sans); font-size: 12.5px; color: var(--ink-3); margin: 10px 0 0; }
.doc-body { max-width: 68ch; margin-top: 34px; }
.doc-body h2 {
  font-size: 22px; margin: 42px 0 10px;
  padding-bottom: 7px; border-bottom: 1px solid var(--line);
}
.doc-body h3 { font-size: 18px; margin: 26px 0 6px; }
.doc-body p, .doc-body li { color: var(--ink-2); }
.doc-body p { margin: 0 0 14px; }
.doc-body ul, .doc-body ol { margin: 0 0 16px; padding-left: 22px; display: grid; gap: 8px; }
.doc-body strong { color: var(--ink); }
.doc-lede {
  font-size: 18px; font-style: italic; color: var(--ink-2);
  border-left: 3px solid var(--line-2); padding-left: 18px; margin-bottom: 26px;
}
.doc-toc {
  background: var(--panel-2); border: 1px solid var(--line);
  padding: 18px 22px; margin-bottom: 34px;
}
.doc-toc ol { margin: 8px 0 0; padding-left: 20px; gap: 5px; }

/* A table of what is stored — the cookie page's whole point. */
.tbl { width: 100%; border-collapse: collapse; margin: 0 0 22px; font-size: 14.5px; }
.tbl th {
  text-align: left; font-family: var(--sans); font-size: 10px; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3);
  padding: 0 12px 8px 0; border-bottom: 1px solid var(--ink); white-space: nowrap;
}
.tbl td { padding: 10px 12px 10px 0; border-bottom: 1px dotted var(--line); vertical-align: top; color: var(--ink-2); }
.tbl td:first-child { font-family: var(--mono); font-size: 12.5px; color: var(--ink); white-space: nowrap; }
@media (max-width: 620px) {
  .tbl, .tbl tbody, .tbl tr, .tbl td { display: block; width: 100%; }
  .tbl thead { display: none; }
  .tbl tr { border-bottom: 1px solid var(--line); padding: 12px 0; }
  .tbl td { border: 0; padding: 2px 0; }
}

/* --- contact ------------------------------------------------------------- */
.cards { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); margin-top: 30px; }
@media (min-width: 760px) { .cards { grid-template-columns: 1fr 1fr; } }
.card { background: var(--panel); padding: 26px 26px 30px; }
.card h2 { font-size: 21px; margin-bottom: 8px; }
.card p { color: var(--ink-2); margin: 0 0 14px; font-size: 15.5px; }
.card .big {
  font-size: 17px; word-break: break-word;
}

/* --- footer -------------------------------------------------------------- */
.foot-wrap { background: var(--panel-2); border-top: 1px solid var(--line); padding: var(--sp-7) 0; }
.foot { display: grid; gap: 30px; }
@media (min-width: 860px) { .foot { grid-template-columns: minmax(0,1fr) auto; align-items: start; } }
.foot-line { font-style: italic; color: var(--ink-3); margin: 6px 0 8px; font-size: 15px; }
.foot-about { color: var(--ink-2); margin: 0 0 18px; font-size: 15px; max-width: 60ch; }
/* The cookie note: a line among the legal ones, never over the page. */
.foot-ck { margin-top: 10px; }
.foot-ck .linky { padding: 0; font-size: inherit; color: inherit; }
/* The analytics choice — only printed when the site has an analytics ID, and
   hidden until site.js finds no stored choice. Two equal buttons. */
.ck-bar {
  position: fixed; left: 12px; right: 12px; bottom: 12px; z-index: 60;
  max-width: 760px; margin-inline: auto;
  display: flex; flex-wrap: wrap; gap: 12px 20px; align-items: center; justify-content: space-between;
  padding: 14px 18px; background: var(--panel); color: var(--ink);
  border: 1px solid var(--line-2); border-radius: 4px; box-shadow: var(--shadow);
  font-family: var(--sans); font-size: 14px; line-height: 1.5;
}
.ck-bar[hidden] { display: none; }
.ck-bar p { margin: 0; flex: 1 1 320px; color: var(--ink-2); }
.ck-bar a { color: var(--ink); }
.ck-btns { display: flex; gap: 10px; flex: 0 0 auto; }
.ck-btn {
  min-height: 44px; padding: 0 18px; cursor: pointer; font: inherit; font-weight: 600;
  background: var(--panel); color: var(--ink); border: 1px solid var(--ink); border-radius: 3px;
}
.ck-btn:hover { background: var(--panel-3); }
.foot-links { display: flex; flex-wrap: wrap; gap: 2px 22px; font-family: var(--sans); font-size: 13px; align-items: center; }
.foot-links a { color: var(--ink-2); text-decoration: none; padding: 9px 0; }
.foot-links a:hover { color: var(--ink); text-decoration: underline; }
.foot-links.is-quiet a, .foot-links.is-quiet .linky { font-size: 12.5px; color: var(--ink-3); }
.foot-links.is-quiet a:hover, .foot-links.is-quiet .linky:hover { color: var(--ink); }
.foot-legal { font-family: var(--sans); font-size: 12px; color: var(--ink-3); line-height: 1.9; margin: 18px 0 0; max-width: 56ch; }
.foot-social .kicker { margin-bottom: 10px; }
.social { display: flex; gap: 10px; flex-wrap: wrap; }
.social a {
  width: 42px; height: 42px; display: grid; place-items: center;
  border: 1px solid var(--line-2); color: var(--ink-2); border-radius: 3px; text-decoration: none;
}
.social a:hover { color: var(--ink); background: var(--panel); }

/* ==========================================================================
   THE PRODUCT, DRAWN LIVE — the four pictures on the front page (_demo.php).

   HTML and CSS in place of screenshots, drawn with the tokens at the top of
   this file, so they follow light and dark (and the switch in the bar) with
   no script. Each device is a size container and everything inside is sized
   in `em` from ONE font-size set in container units — so the whole drawing
   scales like a picture, and a narrow container gets a simpler layout (fewer
   tiles, four days) rather than unreadable type.
   ========================================================================== */
@property --v { syntax: "<number>"; inherits: true; initial-value: 0; }

.dv { container-type: inline-size; text-align: left; user-select: none; -webkit-user-select: none; }
.dv * { box-sizing: border-box; }
.dv-screen {
  position: relative; overflow: hidden;
  background: var(--bg); color: var(--ink);
  /* The app's faces by role, as in the app: reading in the sans, headings in
     the serif, the wall's figures in the mono. */
  font-family: var(--sans); line-height: 1.3;
}
.dv b { font-weight: 700; }
.dv-ic { width: 1.5em; height: 1.5em; display: block; }

/* --- a tablet ----------------------------------------------------------- */
.dv-tab {
  padding: clamp(7px, 1.3vw, 14px);
  background: var(--bezel); border-radius: clamp(14px, 2.4vw, 28px);
  box-shadow: 0 0 0 1px var(--line-2), 0 30px 60px -34px rgba(0,0,0,.6), 0 2px 6px -2px rgba(0,0,0,.25);
}
.dv-tab > .dv-screen {
  border-radius: clamp(4px, .9vw, 10px);
  font-size: clamp(6.5px, 1.45cqi, 15px);
  padding: 1.5em 1.9em 1.7em;
}

/* the masthead: household, date, clock, today's ring */
.dv-mast {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto auto;
  align-items: center; gap: 0 1.3em;
  padding-bottom: .9em; border-bottom: 3px double var(--ink);
}
.dv-hh { display: flex; align-items: baseline; flex-wrap: wrap; gap: .1em 1.4em; min-width: 0; }
.dv-hh b { font-family: var(--serif); font-weight: 400; font-size: 2em; font-variant: small-caps; letter-spacing: .05em; line-height: 1.1; }
.dv-hh span {
  font-family: var(--sans); font-size: .74em; font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase; color: var(--ink-2); white-space: nowrap;
}
.dv-clock { font-family: var(--mono); font-size: 3em; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.dv-ring {
  position: relative; width: 3.7em; height: 3.7em; border-radius: 50%;
  display: grid; place-content: center; text-align: center; line-height: 1;
}
.dv-ring::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(var(--ink) calc(var(--v) * 1turn), var(--line) 0);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - .26em), #000 calc(100% - .24em));
          mask: radial-gradient(farthest-side, transparent calc(100% - .26em), #000 calc(100% - .24em));
}
.dv-ring b { font-weight: 400; font-size: 1.35em; }
.dv-ring small { font-family: var(--sans); font-size: .68em; color: var(--ink-3); margin-top: .15em; }
.dv-btns { display: flex; gap: .55em; }
.dv-btn {
  width: 3.5em; height: 3.5em; display: grid; place-items: center;
  border: 1px solid var(--line-2); background: var(--panel); color: var(--ink); border-radius: 3px;
}
.dv-btn.is-pri { background: var(--ink); color: var(--bg); border-color: var(--ink); }

/* section heads: EVENTS, CHORES & ONE-OFFS */
.dv-h {
  display: flex; justify-content: space-between; gap: 1em;
  font-family: var(--sans); font-size: .74em; font-weight: 700; letter-spacing: .2em;
  text-transform: uppercase; color: var(--ink-2);
  padding: 1.5em 0 .6em; margin-bottom: 1.2em; border-bottom: 1px solid var(--ink);
}
.dv-h span + span { font-weight: 500; }

/* events */
.dv-events { display: grid; grid-template-columns: 1fr 1fr; gap: .9em 1.6em; }
.dv-ev { display: grid; gap: .1em; padding: .3em 0 .35em 1.1em; border-left: 3px solid var(--ink); }
.dv-at { font-family: var(--mono); font-weight: 700; font-variant-numeric: tabular-nums; font-size: 1.05em; }
.dv-et { font-size: 1.65em; line-height: 1.15; }
.dv-ev b, .dv-by b {
  color: var(--c, var(--ink-2));
  color: color-mix(in srgb, var(--c, var(--ink-2)) 80%, var(--ink));
}
.dv-ev b { font-size: .95em; }
.dv b.is-any { color: var(--ink-3); font-weight: 400; font-style: italic; }

/* the chore and one-off tiles */
.dv-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .8em; }
.dv-tile {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto 1fr;
  gap: 0 .8em; min-height: 8.6em; padding: 1em 1.2em 1.05em 1.3em;
  background: var(--panel); border: 1px solid var(--line); border-left: .26em solid var(--c);
}
.dv-tt { min-width: 0; }
.dv-room {
  display: block; margin-bottom: .2em;
  font-family: var(--sans); font-size: .68em; font-weight: 700; letter-spacing: .2em;
  text-transform: uppercase; color: var(--ink-2);
}
.dv-ti { display: block; font-size: 1.42em; line-height: 1.15; }
.dv-pts { font-family: var(--mono); font-size: 1.9em; line-height: 1; text-align: center; font-variant-numeric: tabular-nums; }
.dv-pts small {
  display: block; margin-top: .15em;
  font-family: var(--sans); font-size: .34em; letter-spacing: .22em; text-transform: uppercase; color: var(--ink-3);
}
.dv-by { grid-column: 1 / -1; align-self: end; margin-top: 1.3em; font-size: 1.02em; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dv-by i { font-style: italic; }
.dv-tile.is-done { background: var(--panel-2); border-left-color: var(--good); }
.dv-tile.is-done .dv-ti, .dv-tile.is-done .dv-room { text-decoration: line-through; text-decoration-thickness: 1px; color: var(--ink-3); }
.dv-tile.is-done .dv-pts { color: var(--good); }
.dv-stamp {
  display: inline-block; margin-left: .35em; padding: .12em .5em .1em;
  font-family: var(--sans); font-size: .62em; font-weight: 700; font-style: italic;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--good); border: 1.5px solid var(--good); border-radius: 2px;
  transform: rotate(-4deg); vertical-align: .15em;
}

/* Done today: the wall's adaptive density shrinks a ticked chore or one-off
   to a small pill after the open ones, so what is still to do keeps the room.
   The tick is in the colour of whoever did it. */
.dv-dones { display: flex; flex-wrap: wrap; gap: .5em .6em; margin-top: .9em; }
.dv-done {
  display: inline-flex; align-items: center; gap: .45em; min-width: 0; max-width: 100%;
  padding: .32em .85em .32em .55em; background: var(--panel-2); border: 1px solid var(--line); border-radius: 999px;
  font-size: 1em; color: var(--ink-2); white-space: nowrap;
}
.dv-donei { width: 1.15em; height: 1.15em; flex: none; color: var(--good); }
.dv-dt { overflow: hidden; text-overflow: ellipsis; }
.dv-done b { font-weight: 400; font-style: italic; color: color-mix(in srgb, var(--c) 80%, var(--ink)); }

/* the month: the one goal the whole house plays for together */
.dv-month {
  display: grid; grid-template-columns: auto minmax(4em, 1fr) auto auto; align-items: center; gap: .4em 1.2em;
  margin-top: 1.4em; padding: 1em 1.4em;
  background: var(--panel); border: 1px solid var(--line); border-left: 3px solid var(--ink);
}
.dv-lab { font-family: var(--sans); font-size: .72em; font-weight: 500; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-2); white-space: nowrap; }
.dv-bar { position: relative; height: .8em; background: var(--panel-3); }
.dv-bar i { position: absolute; inset: 0; background: var(--ink); transform-origin: 0 50%; transform: scaleX(var(--v)); }
.dv-bar em { position: absolute; top: -.4em; bottom: -.4em; left: calc(var(--goal) * 100%); width: 2px; background: var(--flag); }
.dv-pct { font-family: var(--mono); font-size: 1.9em; line-height: 1; font-weight: 400; font-variant-numeric: tabular-nums; }
.dv-togo { font-size: 1.05em; color: var(--ink-2); white-space: nowrap; }

/* NARROW (a phone, mostly): fewer tiles at a size that can be read, rather
   than the whole tablet shrunk until its text is a few pixels tall. */
@container (max-width: 560px) {
  .dv-tab > .dv-screen { font-size: 3.2cqi; padding: 1.3em 1.4em 1.4em; }
  .dv-mast .dv-btns, .dv-tiles .dv-more { display: none; }
  .dv-mast { grid-template-columns: minmax(0, 1fr) auto auto; }
  .dv-hh { flex-direction: column; gap: .3em; }
  .dv-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dv-tile { min-height: 8em; }
  .dv-month { grid-template-columns: auto minmax(3em, 1fr) auto; }
  .dv-togo { grid-column: 1 / -1; }
}

/* --- the week, on a tablet ------------------------------------------------ */
.dv-tab.is-week > .dv-screen { padding: 0; font-size: clamp(6px, 1.6cqi, 13px); }
.dv-wkhead { display: flex; align-items: center; gap: 1em; padding: 1.3em 1.6em 1.2em; border-bottom: 1px solid var(--line); }
.dv-wkhead .dv-hh { flex-direction: column; gap: .15em; margin-right: auto; }
.dv-wkhead .dv-hh b { font-size: 2.1em; }
.dv-wkhead .dv-btn { width: 3.2em; height: 3.2em; font-size: 1em; }
.dv-btn.is-t { font-size: 1.5em; line-height: 1; }
.dv-btn.is-t.is-w { width: auto; padding: 0 .8em; font-size: 1.15em; }
.dv-days {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  height: 37em; overflow: hidden;
  -webkit-mask: linear-gradient(to bottom, #000 82%, transparent);
          mask: linear-gradient(to bottom, #000 82%, transparent);
}
.dv-day { display: flex; flex-direction: column; gap: .55em; padding: 0 .55em .8em; min-width: 0; }
.dv-day + .dv-day { border-left: 1px solid var(--line); }
.dv-day.is-today { background: var(--panel-2); box-shadow: inset 0 .3em 0 var(--ink); }
.dv-dh {
  display: flex; align-items: baseline; gap: .45em; margin: 0 -.55em .2em; padding: 1em .9em .7em;
  font-family: var(--sans); border-bottom: 1px solid var(--line);
}
.dv-dh span { font-size: .78em; font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-2); }
.dv-dh b { font-size: 1.55em; }
.dv-pill {
  display: grid; gap: .2em; padding: .55em .6em .55em .7em;
  background: var(--panel); border: 1px solid var(--line); border-left: .25em solid var(--c);
}
.dv-pill small { font-family: var(--sans); font-size: .62em; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-3); }
.dv-pill b { font-size: 1.12em; font-weight: 600; line-height: 1.2; overflow-wrap: anywhere; }
.dv-pill b em { font-style: normal; font-family: var(--mono); font-size: .88em; color: var(--ink-2); }
.dv-pill span { display: flex; align-items: center; gap: .4em; font-family: var(--sans); font-size: .82em; font-weight: 600; color: var(--ink-2); min-width: 0; }
.dv-pill span i { flex: none; width: .75em; height: .75em; border-radius: 50%; background: var(--c); }
.dv-pill span u { margin-left: auto; text-decoration: none; font-family: var(--mono); }
.dv-pill.is-oneoff { border-left-style: dashed; }
.dv-pill.is-ev { background: var(--bg); }
/* Half a page wide (the tour's stage on a small laptop): four days and the
   edge of a fifth. */
@container (max-width: 560px) {
  .dv-tab.is-week > .dv-screen { font-size: 2.35cqi; }
  .dv-days { grid-template-columns: repeat(4, minmax(0, 1fr)) .55fr; height: 34em;
    -webkit-mask-image: linear-gradient(to right, #000 84%, transparent), linear-gradient(to bottom, #000 82%, transparent);
    -webkit-mask-composite: source-in;
            mask-image: linear-gradient(to right, #000 84%, transparent), linear-gradient(to bottom, #000 82%, transparent);
            mask-composite: intersect; }
  .dv-day.dv-late ~ .dv-late { display: none; }
  .dv-wkhead .dv-btn:not(.is-pri) { display: none; }
}
/* On a phone: today and tomorrow at a readable size, with the next day
   showing at the edge so it is plain the week carries on — the planner's own
   phone view is one day at a time. Seven columns at 350px wide set the
   titles at about 3px. The edge day keeps its full width and is cut off,
   rather than squeezed into a word a line. */
@container (max-width: 420px) {
  .dv-tab.is-week > .dv-screen { font-size: 3.3cqi; }
  .dv-days { grid-template-columns: repeat(2, minmax(0, 1fr)) .5fr; height: 30em;
    -webkit-mask-image: linear-gradient(to right, #000 84%, transparent), linear-gradient(to bottom, #000 82%, transparent);
    -webkit-mask-composite: source-in;
            mask-image: linear-gradient(to right, #000 84%, transparent), linear-gradient(to bottom, #000 82%, transparent);
            mask-composite: intersect; }
  .dv-day { display: flex; }
  .dv-day:first-child, .dv-day:nth-child(n+5) { display: none; }
  .dv-day:nth-child(2) { border-left: 0; }
  .dv-day:nth-child(4) { overflow: hidden; }
  .dv-day:nth-child(4) * { white-space: nowrap; overflow: hidden; overflow-wrap: normal; }
  .dv-wkhead .dv-btn:not(.is-pri) { display: none; }
}

/* --- a phone -------------------------------------------------------------- */
.dv-phone {
  padding: 9px; background: var(--bezel); border-radius: 44px;
  box-shadow: 0 0 0 1px var(--line-2), 0 30px 60px -34px rgba(0,0,0,.6), 0 2px 6px -2px rgba(0,0,0,.25);
}
.dv-phone > .dv-screen {
  aspect-ratio: 9 / 19; border-radius: 36px;
  display: flex; flex-direction: column;
  font-size: 3.85cqi; padding: 0 1.4em;
}
.dv-sbar { flex: none; display: flex; align-items: center; justify-content: space-between; height: 3.8em; margin: 0 .4em; font-family: var(--sans); font-size: .95em; }
.dv-notch { width: 7.5em; height: 2em; border-radius: 1em; background: var(--bezel); }
.dv-sig { display: flex; align-items: flex-end; gap: .18em; height: .9em; }
.dv-sig i { width: .28em; background: var(--ink); border-radius: 1px; }
.dv-sig i:nth-child(1) { height: 45%; } .dv-sig i:nth-child(2) { height: 70%; } .dv-sig i:nth-child(3) { height: 100%; }
.dv-phone .dv-mast { grid-template-columns: minmax(0, 1fr) auto auto; gap: 0 .8em; padding-top: .3em; }
.dv-phone .dv-hh { flex-direction: column; gap: .35em; }
.dv-phone .dv-hh b { font-size: 1.65em; }
.dv-phone .dv-hh span { font-size: .66em; }
.dv-phone .dv-clock { font-size: 2.3em; }
.dv-phone .dv-ring { width: 3.2em; height: 3.2em; }
.dv-phone .dv-h { padding-top: 1.1em; margin-bottom: .9em; }
.dv-phone .dv-events { grid-template-columns: 1fr; }
.dv-phone .dv-et { font-size: 1.45em; }
.dv-phone .dv-tiles {
  grid-template-columns: 1fr; grid-auto-rows: max-content; gap: .65em; flex: 1 1 0; min-height: 0; overflow: hidden; align-content: start;
  -webkit-mask: linear-gradient(to bottom, #000 85%, transparent);
          mask: linear-gradient(to bottom, #000 85%, transparent);
}
.dv-phone .dv-tile { min-height: 0; padding: .8em 1em .85em 1.1em; }
.dv-phone .dv-by { margin-top: .6em; }
.dv-phone .dv-ti { font-size: 1.3em; }
.dv-phone .dv-pts { font-size: 1.6em; }
.dv-foot { flex: none; display: grid; gap: .8em; padding: .5em 0 1.5em; }
.dv-month.is-compact { margin-top: .5em; grid-template-columns: auto minmax(2em, 1fr) auto; padding: .8em 1em; gap: .4em .8em; }
.dv-month.is-compact .dv-togo { display: none; }
.dv-month.is-compact .dv-pct { font-size: 1.6em; }
.dv-foot .dv-btns { justify-self: end; }
.dv-foot .dv-btn { width: 3.3em; height: 3.3em; }

/* --- the achievements window --------------------------------------------- */
.frame.is-win { max-width: 560px; }
.dv-win { border: 1px solid var(--ink); background: var(--panel); box-shadow: var(--shadow); }
.dv-win > .dv-screen { background: var(--panel); font-size: clamp(10px, 2.85cqi, 15px); }
.dv-winhead { display: flex; align-items: center; justify-content: space-between; padding: 1.3em 1.7em 1.2em; border-bottom: 1px solid var(--line); }
.dv-winhead b { font-family: var(--serif); font-weight: 400; font-size: 1.9em; font-variant: small-caps; letter-spacing: .05em; }
.dv-btn.is-x { width: 2.6em; height: 2.6em; font-size: 1.1em; color: var(--ink-2); }
.dv-winbody { padding: 1.4em 1.7em 1.5em; }
.dv-big b { display: block; font-size: 4.4em; line-height: .95; }
.dv-big span {
  display: block; margin-top: .6em;
  font-family: var(--sans); font-size: .8em; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-2);
}
.dv-note { margin: .8em 0 0; max-width: 34em; font-size: 1.08em; color: var(--ink-2); }
.dv-h.is-strong { border-bottom-width: 2px; margin-bottom: 0; color: var(--ink); }
.dv-ach { display: grid; grid-template-columns: 2.4em minmax(0, 1fr) auto; gap: 0 1.1em; align-items: start; padding: 1em 0; border-bottom: 1px solid var(--line); }
.dv-ach:last-child { border-bottom: 0; padding-bottom: 0; }
.dv-achic { width: 2.2em; height: 2.2em; margin-top: .2em; color: var(--ink); }
.dv-ach b { display: block; font-weight: 400; font-size: 1.3em; line-height: 1.2; }
.dv-ach > div > span { display: block; color: var(--ink-2); }
.dv-ach small { display: flex; align-items: center; gap: .5em; margin-top: .3em; font-family: var(--mono); font-size: .9em; color: var(--ink-2); }
.dv-ach small em { font-family: var(--sans); font-style: normal; font-weight: 700; font-size: .9em; letter-spacing: .2em; text-transform: uppercase; }
.dv-avs { display: flex; padding-left: .3em; }
.dv-avs i {
  width: 2em; height: 2em; margin-left: -.35em; border-radius: 50%;
  display: grid; place-items: center; font-style: normal;
  font-family: var(--sans); font-size: .85em; font-weight: 700; color: #fff;
  background: var(--c); box-shadow: 0 0 0 2px var(--panel);
}
.dv-ach.is-open { opacity: .92; }
.dv-prog i { display: block; width: 8em; height: .45em; background: linear-gradient(to right, var(--ink) calc(var(--v) * 100%), var(--panel-3) 0); }
@container (max-width: 380px) { .dv-avs i { width: 1.8em; height: 1.8em; } }
/* The two windows on a phone: the text was held at 10px; the windows are
   simple enough to take a size that reads at arm's length. */
@container (max-width: 480px) { .dv-win > .dv-screen { font-size: 3.6cqi; } }

/* --- the month window: the one goal, for the whole house ------------------ */
.dv-bar.is-big { display: block; height: 1.1em; margin-top: 1.3em; }
.dv-bar.is-big em { top: -.45em; bottom: -.45em; width: 3px; }
.dv-scale {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 1em; margin-top: .7em;
  font-family: var(--sans); font-size: .8em; color: var(--ink-3);
}
.dv-scale .is-mid { color: var(--flag); font-weight: 700; }
.dv-scale span:last-child { text-align: right; }
.dv-prize {
  display: grid; grid-template-columns: 2.4em minmax(0, 1fr); gap: 0 1em; align-items: start;
  margin-top: 1.4em; padding: 1em 1.2em; background: var(--panel-2); border: 1px solid var(--line);
}
.dv-gift { font-size: 1.9em; line-height: 1.1; text-align: center; }
.dv-prize b { display: block; font-weight: 400; font-size: 1.55em; line-height: 1.15; }
.dv-prize span { display: block; margin-top: .3em; color: var(--ink-2); }
.dv-mrow { display: grid; grid-template-columns: 3em minmax(0, 1fr) auto; gap: 1em; align-items: center; padding: .75em 0; border-bottom: 1px solid var(--line); }
.dv-mrow:last-child { border-bottom: 0; padding-bottom: 0; }
.dv-m { font-family: var(--sans); font-size: .8em; font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-2); }
.dv-r { display: flex; align-items: center; gap: .5em; min-width: 0; }
.dv-r i { color: var(--ink-3); }
.dv-cup { width: 1.2em; height: 1.2em; color: var(--good); flex: none; }
.dv-p { font-variant-numeric: tabular-nums; color: var(--ink-2); }
.dv-mrow.is-won .dv-p { color: var(--ink); }

/* ==========================================================================
   PREMIUM, DRAWN — one picture per released Premium feature (index.php ›
   #extras, _demo.php › "Premium, drawn"). The same hairline grid as the
   plans, so it reads as part of the same offer; the pictures sit on the
   darker paper so each cell has a picture half and a words half.
   ========================================================================== */
.px-grid {
  margin: var(--sp-6) 0 0; display: grid; gap: 1px;
  background: var(--line); border: 1px solid var(--line);
}
@media (min-width: 820px) { .px-grid { grid-template-columns: 1fr 1fr; } .px.is-wide { grid-column: 1 / -1; } }
.px { margin: 0; background: var(--panel); display: grid; grid-template-rows: 1fr auto; min-width: 0; }
.px-pic {
  position: relative; isolation: isolate; min-width: 0;
  display: grid; place-items: center;
  padding: clamp(18px, 3.4vw, 36px) clamp(16px, 3.4vw, 40px);
  background: var(--panel-2); border-bottom: 1px solid var(--line);
}
/* The same soft wash of the family's colours as behind the wall in the hero,
   quieter, so the drawings sit on something rather than on flat paper. */
.px-pic::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: var(--glow);
  background:
    radial-gradient(50% 60% at 20% 70%, color-mix(in srgb, var(--p-ana) 14%, transparent), transparent 70%),
    radial-gradient(45% 55% at 85% 25%, color-mix(in srgb, var(--p-clara) 12%, transparent), transparent 70%);
}
.px figcaption { padding: var(--sp-5) var(--sp-6) var(--sp-6); }
.px h3 { font-size: 21px; margin-bottom: var(--sp-2); }
.px figcaption p { margin: 0; color: var(--ink-2); font-size: 15.5px; line-height: 1.55; max-width: 60ch; }
@media (max-width: 600px) { .px figcaption { padding: var(--sp-4) var(--sp-5) var(--sp-5); } }
.px-pic > .dv { width: 100%; }
.px-wifi .px-pic > .dv { max-width: 520px; }
.px-households .px-pic > .dv { max-width: 400px; }

/* --- the guest Wi-Fi card, open on the wall ------------------------------- */
.dv-tab.is-wifi > .dv-screen { font-size: 2.3cqi; padding: 1.3em 1.5em 1.5em; }
.dv-tab.is-wifi .dv-mast { grid-template-columns: minmax(0, 1fr) auto auto; }
.dv-tab.is-wifi .dv-hh { flex-direction: column; gap: .3em; }
.dv-tab.is-wifi .dv-mast .dv-btns { display: flex; }
.dv-tab.is-wifi .dv-btn { width: 3em; height: 3em; }
.dv-btn.is-on { box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--ink); }
.dv-under { display: grid; grid-template-columns: 1fr 1fr; gap: .8em; margin-top: 1.4em; }
.dv-under .dv-tile { min-height: 7em; }
/* The scrim the app lays over the wall when a card opens. */
.dv-tab.is-wifi .dv-screen::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: color-mix(in srgb, var(--ink) 34%, transparent);
}
.dv-sheet {
  position: absolute; z-index: 2; left: 50%; top: 56%; translate: -50% -50%;
  width: 50%; background: var(--panel); border: 1px solid var(--line-2); box-shadow: var(--shadow);
}
.dv-sheethead { padding: .8em 1.1em .7em; border-bottom: 1px solid var(--line); }
.dv-sheethead b { font-family: var(--serif); font-weight: 400; font-size: 1.5em; font-variant: small-caps; letter-spacing: .05em; }
.dv-wifi { display: grid; justify-items: center; gap: .7em; padding: 1em 1.2em 1.1em; text-align: center; }
.dv-kick { display: flex; align-items: center; gap: .5em; font-family: var(--sans); font-size: .72em; font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-2); }
.dv-kick .dv-ic { width: 1.4em; height: 1.4em; }
.dv-qr { width: 62%; height: auto; display: block; box-shadow: 0 0 0 1px var(--line); }
.dv-ssid { font-family: var(--mono); font-size: 1.15em; font-weight: 600; }
.dv-hint { font-size: .85em; color: var(--ink-3); font-style: italic; }
.dv-timer { display: block; height: .3em; background: var(--panel-3); }
.dv-timer i { display: block; height: 100%; width: 64%; background: var(--ink); }
@container (max-width: 420px) {
  .dv-tab.is-wifi > .dv-screen { font-size: 3.4cqi; }
  .dv-under .dv-tile:nth-child(n+3) { display: none; }
  .dv-sheet { width: 78%; top: 55%; }
}

/* --- the households window ------------------------------------------------ */
.dv-win.is-houses > .dv-screen { font-size: clamp(10px, 3.6cqi, 15px); }
.dv-hrow {
  display: grid; grid-template-columns: 1.7em minmax(0, 1fr) auto; gap: 0 .9em; align-items: center;
  padding: .9em 1em; border: 1px solid var(--line); background: var(--bg);
}
.dv-hrow + .dv-hrow { margin-top: .6em; }
.dv-hrow.is-on { border-color: var(--ink); background: var(--panel-2); }
.dv-tick { width: 1.7em; height: 1.7em; border-radius: 50%; display: grid; place-items: center; border: 1px solid var(--line-2); }
.dv-hrow.is-on .dv-tick { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.dv-tick .dv-ic { width: 1em; height: 1em; }
.dv-ht b { display: block; font-weight: 400; font-size: 1.3em; line-height: 1.2; }
.dv-ht small { display: block; margin-top: .15em; font-family: var(--sans); font-size: .78em; color: var(--ink-3); }
.dv-here { font-family: var(--sans); font-size: .72em; font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-2); }
.dv-go { font-size: 1.6em; color: var(--ink-3); line-height: 1; }
.dv-add {
  display: flex; align-items: center; justify-content: center; gap: .5em; margin-top: 1em;
  padding: .75em; border: 1px solid var(--line-2); background: var(--panel); border-radius: 3px;
}
.dv-add .dv-ic { width: 1.2em; height: 1.2em; }
.dv-win.is-houses .dv-note { font-size: .92em; }

/* --- the Looks: a small wall each, in its own paper, ink and type ---------
   The values are LOOKS in public/js/themes.js, light and dark, copied the
   same way the page's own Rustic palette is (see the top of this file).

   Only the released Looks are drawn (site_premium_looks()), so the strip is
   two to five walls: --lk-n is how many, and .is-N says the same to the
   rules below. Fewer than five keep the size a wall has in the strip of five
   and sit in the middle, rather than growing to fill the width. */
.dv-looks {
  width: 100%; display: grid; grid-template-columns: repeat(var(--lk-n, 5), minmax(0, 1fr)); gap: clamp(10px, 1.8vw, 20px);
  max-width: calc(var(--lk-n, 5) * 20%); margin-inline: auto;
  text-align: left; user-select: none; -webkit-user-select: none;
}
/* Narrower: five do not fit in a row, and five in rows of two or three leave
   a hole. So the free one stands on a row of its own and the four Premium
   ones share the rows under it — which is also the point being made. Fewer
   than five still fit in a row of four. */
@media (max-width: 760px) {
  .dv-looks { max-width: calc(var(--lk-n, 5) * 25%); }
  .dv-looks.is-5 { grid-template-columns: repeat(4, minmax(0, 1fr)); max-width: none; }
  .dv-looks.is-5 .dv-lk.lk-rustic { grid-column: 1 / -1; width: calc((100% - 3 * clamp(10px, 1.8vw, 20px)) / 4); }
}
/* Rows of two. An odd number puts Rustic on a row of its own, as above. */
@media (max-width: 480px) {
  .dv-looks, .dv-looks.is-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: none; }
  .dv-looks.is-3 .dv-lk.lk-rustic, .dv-looks.is-5 .dv-lk.lk-rustic {
    grid-column: 1 / -1; width: calc((100% - clamp(10px, 1.8vw, 20px)) / 2);
  }
}
.dv-lk { container-type: inline-size; min-width: 0; }
.dv-lks {
  aspect-ratio: 4 / 3.3; overflow: hidden; display: flex; flex-direction: column; gap: 5cqi;
  padding: 7cqi 7cqi 8cqi; font-size: 6.4cqi; line-height: 1.2;
  background: var(--lk-bg); color: var(--lk-ink); font-family: var(--lk-f);
  border: 5cqi solid var(--bezel); border-radius: 9cqi;
  box-shadow: 0 0 0 1px var(--line-2), 0 18px 34px -24px rgba(0,0,0,.55);
}
.lk-mast { display: flex; align-items: baseline; justify-content: space-between; gap: .5em; padding-bottom: .35em; border-bottom: var(--lk-rule, 1px) solid var(--lk-ink); }
.lk-mast b { font-weight: var(--lk-hw, 400); font-variant: var(--lk-hv, normal); text-transform: var(--lk-ht, none); letter-spacing: var(--lk-tr, 0); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lk-mast span { font-weight: 700; font-variant-numeric: tabular-nums; }
.lk-tile {
  display: flex; align-items: center; justify-content: space-between; gap: .4em;
  padding: .45em .55em; background: var(--lk-panel); border: 1px solid var(--lk-line);
  border-left: .32em solid var(--c); border-radius: var(--lk-r, 0);
}
.lk-tile b { font-weight: 600; font-size: .86em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lk-tile u { text-decoration: none; font-variant-numeric: tabular-nums; color: var(--lk-ink2); }
.lk-bar { margin-top: auto; height: .55em; background: var(--lk-line); border-radius: var(--lk-bar, 0); overflow: hidden; }
.lk-bar i { display: block; width: 56%; height: 100%; background: var(--lk-acc); border-radius: inherit; }
.dv-lkcap { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 8px; margin-top: 10px; }
.dv-lkcap b { font-family: var(--serif); font-weight: 400; font-size: 17px; font-variant: small-caps; letter-spacing: .04em; }
.dv-lkcap span { font-family: var(--sans); font-size: 10.5px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; padding: 2px 6px; border-radius: 2px; }
/* Premium in ink, free in the page's one green — the same key as Coming soon. */
.dv-lkcap .is-prem { color: var(--bg); background: var(--ink); }
.dv-lkcap .is-free { color: var(--good); border: 1px solid var(--good); }

.lk-rustic { --lk-bg:#f4f1e8; --lk-panel:#faf8f2; --lk-line:#cdc6b1; --lk-ink:#17150f; --lk-ink2:#57523f; --lk-acc:#17150f;
  --lk-f: var(--serif); --lk-hv: small-caps; --lk-tr: .05em; --lk-r: 2px; }
.lk-industrial { --lk-bg:#e8e9ea; --lk-panel:#f4f5f6; --lk-line:#b3b7bb; --lk-ink:#16181a; --lk-ink2:#454a4f; --lk-acc:#8a4f00;
  --lk-f: "Archivo Narrow", "Roboto Condensed", "Helvetica Neue Condensed", "Arial Narrow", "Liberation Sans Narrow", sans-serif;
  --lk-hw: 700; --lk-ht: uppercase; --lk-tr: .06em; --lk-rule: 2px; }
.lk-modern { --lk-bg:#ffffff; --lk-panel:#f6f6f9; --lk-line:#e6e6ef; --lk-ink:#111116; --lk-ink2:#51516a; --lk-acc:#0f7a46;
  --lk-f: "Avenir Next", Avenir, "Century Gothic", "URW Gothic", system-ui, sans-serif; --lk-hw: 700; --lk-tr: -.02em; --lk-r: 6px; --lk-bar: 99px; }
.lk-minimal { --lk-bg:#fbfbfa; --lk-panel:#ffffff; --lk-line:#e5e5e2; --lk-ink:#2a2a28; --lk-ink2:#5e5e5a; --lk-acc:#5e5e5a;
  --lk-f: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif; --lk-hw: 300; --lk-tr: .01em; }
.lk-arcade { --lk-bg:#f3f1ff; --lk-panel:#ffffff; --lk-line:#ded8ff; --lk-ink:#14103a; --lk-ink2:#463f7d; --lk-acc:#066a54;
  --lk-f: "Avenir Next", Avenir, "Century Gothic", "URW Gothic", system-ui, sans-serif; --lk-hw: 700; --lk-tr: .02em; --lk-r: 5px; --lk-bar: 99px; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .lk-rustic { --lk-bg:#191918; --lk-panel:#232322; --lk-line:#3a3a38; --lk-ink:#eeedea; --lk-ink2:#b2b0aa; --lk-acc:#eeedea; }
  :root:not([data-theme]) .lk-industrial { --lk-bg:#1d1f21; --lk-panel:#26292c; --lk-line:#3a3e42; --lk-ink:#e6e8ea; --lk-ink2:#aab1b7; --lk-acc:#f2a03d; }
  :root:not([data-theme]) .lk-modern { --lk-bg:#0f0f14; --lk-panel:#18181f; --lk-line:#242430; --lk-ink:#f2f2f7; --lk-ink2:#b4b4c6; --lk-acc:#4dd694; }
  :root:not([data-theme]) .lk-minimal { --lk-bg:#121212; --lk-panel:#1d1d1d; --lk-line:#262626; --lk-ink:#ececea; --lk-ink2:#a9a9a5; --lk-acc:#a9a9a5; }
  :root:not([data-theme]) .lk-arcade { --lk-bg:#0a0817; --lk-panel:#171333; --lk-line:#241f45; --lk-ink:#e9e6ff; --lk-ink2:#aba6d8; --lk-acc:#5ef2c7; }
}
:root[data-theme="dark"] .lk-rustic { --lk-bg:#191918; --lk-panel:#232322; --lk-line:#3a3a38; --lk-ink:#eeedea; --lk-ink2:#b2b0aa; --lk-acc:#eeedea; }
:root[data-theme="dark"] .lk-industrial { --lk-bg:#1d1f21; --lk-panel:#26292c; --lk-line:#3a3e42; --lk-ink:#e6e8ea; --lk-ink2:#aab1b7; --lk-acc:#f2a03d; }
:root[data-theme="dark"] .lk-modern { --lk-bg:#0f0f14; --lk-panel:#18181f; --lk-line:#242430; --lk-ink:#f2f2f7; --lk-ink2:#b4b4c6; --lk-acc:#4dd694; }
:root[data-theme="dark"] .lk-minimal { --lk-bg:#121212; --lk-panel:#1d1d1d; --lk-line:#262626; --lk-ink:#ececea; --lk-ink2:#a9a9a5; --lk-acc:#a9a9a5; }
:root[data-theme="dark"] .lk-arcade { --lk-bg:#0a0817; --lk-panel:#171333; --lk-line:#241f45; --lk-ink:#e9e6ff; --lk-ink2:#aba6d8; --lk-acc:#5ef2c7; }

/* --- questions ---------------------------------------------------------
   The FAQ: a question per line, the answer one press away. <details> so it
   works with no script and every answer is in the page for a search engine. */
.faq { margin-top: var(--sp-6); border-top: 1px solid var(--line); max-width: 800px; }
/* Wide: the question heading and "Something else?" stand in a left-hand
   column the questions take the
   other two thirds. It used to be one 800px column with a third of the page
   empty beside it, and the heading pushed the whole list a screen down. */
@media (min-width: 1000px) {
  .faq-band {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    grid-template-rows: auto 1fr;
    column-gap: var(--sp-7); align-items: start;
  }
  .faq-band > .band-head { grid-column: 1; grid-row: 1; }
  .faq-band > .faq { grid-column: 2; grid-row: 1 / span 2; margin-top: 0; max-width: none; }
  .faq-band > .faq-more { grid-column: 1; grid-row: 2; align-self: start; }
}
.faq-q { border-bottom: 1px solid var(--line); }
.faq-q summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  padding: 16px 2px; min-height: 48px;
}
.faq-q summary::-webkit-details-marker { display: none; }
.faq-q summary h3 { font-size: clamp(18px, 2.3vw, 21px); line-height: 1.3; }
.faq-q summary::after {
  content: ""; flex: none; width: 9px; height: 9px; margin: 0 6px 5px 0;
  border-right: 1.6px solid var(--ink-3); border-bottom: 1.6px solid var(--ink-3);
  transform: rotate(45deg); transition: transform .2s ease;
}
.faq-q[open] summary::after { transform: translateY(4px) rotate(-135deg); }
.faq-q summary:hover h3 { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }
.faq-q p { margin: -4px 0 var(--sp-5); line-height: 1.55; color: var(--ink-2); max-width: 64ch; font-size: 16.5px; }
.faq-more { margin: var(--sp-5) 0 0; color: var(--ink-2); font-size: 16px; }
@media (prefers-reduced-motion: reduce) { .faq-q summary::after { transition: none; } }

/* --- motion: "Settle + Thread" (site.js) ----------------------------------
   Every class here is added by site.js, never written into the markup: with
   no JavaScript there is no `.rise`, no `.is-undocked`, and the page is simply
   a page. That is the difference between a progressive enhancement and a
   blank screen.

   A band waiting to arrive is 12px low and FULLY VISIBLE — never transparent:
   a page that is blank until scrolled is blank to link previews, full-page
   captures, search tools and anybody whose phone is slow to run the script.
   The arrival itself is a spring played by site.js, so there is no transition
   here. Once it is up it is an ordinary element again. */
.rise { transform: translateY(12px); }
.rise.is-up { transform: none; }

/* The picture of the wall grows to its size from the top edge down. */
.shot.is-growing { transform-origin: 50% 0; }

/* THE TOUR, PINNED. One stage holds the three pictures; the words scroll past
   it and each step owns about a screen of scrolling, so a picture holds still
   long enough to be looked at, and scrolling back up brings the one before it
   back. The pictures are stacked in the middle of the stage and scaled (the
   `scale` property, set by site.js, so animations are free to use transform)
   until the tallest of them fits — a phone drawing is taller than a phone.

   Beside the words from 900px; above them below that, with the page's own
   paper behind it so the words pass cleanly underneath.

   "About a screen" is a little less than one (82svh on a phone, 88svh less
   the bar beside it): at a full screen each step's few lines stood alone in
   a screenful of empty paper between one step and the next, which read as
   gaps rather than as pauses. Still long enough to look at each picture. */
.tour.is-staged {
  --bar-h: 65px;
  --stage-h: min(44svh, 420px);
  display: grid; grid-template-columns: minmax(0, 1fr);
  border-top: 1px solid var(--line);
}
.tour.is-staged .tour-step {
  display: block; margin: 0; padding: 26px 0 0; border: 0;
  min-height: 82svh;
}
/* The last picture gets its screen of scrolling too, before the stage lets
   go and the next section comes up. */
.tour.is-staged .tour-step:last-of-type { min-height: calc(135svh - var(--bar-h) - var(--stage-h)); padding-bottom: 35svh; }
.tour-stage {
  position: sticky; top: var(--bar-h); z-index: 2;
  height: var(--stage-h);
  margin-inline: calc(-1 * var(--gut)); padding: 12px var(--gut);
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
.tour-stage > .frame {
  position: absolute; left: 50%; top: 50%; margin: 0;
  translate: -50% -50%; scale: var(--fit, 1); transform-origin: 50% 50%;
  width: calc(100% - 2 * var(--gut));
  visibility: hidden; opacity: 0;
}
.tour-stage > .frame.is-phone { width: min(290px, calc(100% - 2 * var(--gut))); }
.tour-stage > .frame.is-win { width: min(560px, calc(100% - 2 * var(--gut))); max-width: none; }
.tour-stage > .frame.is-on,
.tour-stage > .frame.is-leaving { visibility: visible; opacity: 1; }
.tour-stage > .frame.is-leaving { z-index: 1; pointer-events: none; }
@media (min-width: 900px) {
  .tour.is-staged {
    --stage-h: calc(100svh - var(--bar-h) - 48px);
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    column-gap: clamp(30px, 5vw, 70px); align-items: start;
    border-top: 0;
  }
  .tour.is-staged .tour-step {
    grid-column: 1; padding: 0;
    min-height: calc(88svh - var(--bar-h));
    display: flex; flex-direction: column; justify-content: center;
  }
  .tour.is-staged .tour-step:last-of-type { min-height: calc(140svh - var(--bar-h)); padding-bottom: 40svh; }
  .tour-stage {
    grid-column: 2; grid-row: 1 / span 4; align-self: start;      /* one row per step */
    top: calc(var(--bar-h) + 24px);
    margin: 0; padding: 0; background: none; border: 0;
  }
  .tour-stage > .frame { width: 100%; }
  .tour-stage > .frame.is-phone { width: min(290px, 100%); }
  .tour-stage > .frame.is-win { width: min(560px, 100%); }
}

/* "Start free" in the bar, on the front page, while the hero's own is still
   on screen: kept in its place (nothing in the bar shifts) but not there. */
.bar-cta .btn.is-undocked { visibility: hidden; opacity: 0; }
/* The hero's button on its way up into the bar. */
.dock-ghost {
  position: fixed; z-index: 45; margin: 0;
  transform-origin: 0 0; pointer-events: none;
  min-height: 0; padding: 0; white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  .rise { transform: none; }
  .bar-cta .btn.is-undocked { visibility: visible; opacity: 1; }
}
