/* Deckist's public pages, and the masthead and footer every page shares: the card box. White
   cards on a quiet desk, the words on a card in Literata, the box's labels in Instrument Sans,
   one moss green. The tokens are on :root in deckist.css (both schemes); the brief and the
   critique passes are in docs/DESIGN.md. Scoped to body.mk; the web client is body.mk.app. */
.mk { min-height: 100vh; display: flex; flex-direction: column; background: var(--desk); color: var(--ink);
  --edge: clamp(1rem, 4vw, 3rem); }
.mk > * { flex: none; }
.mk > main { flex: 1; }
.mk-wrap { width: min(1240px, 100% - 2 * var(--edge)); margin-inline: auto; }
:where(.mk) p { color: var(--ink-2); }

/* Wrap control: two short sentences break between them or not at all (.sent), a phrase that
   must stay whole stays whole (.nw), and a sentence that is its own line is a block (.line). */
.mk .sent { display: inline-block; }
.mk .nw { white-space: nowrap; }
.mk .line { display: block; }
.mk .vh { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0; color: var(--ink); }

/* A keyboard's way past the masthead, out of sight until it has focus. */
.skip { position: absolute; left: 1rem; top: -5rem; z-index: 100; padding: 0.65rem 1rem; border-radius: 7px;
  background: var(--ink); color: var(--on-ink); font-weight: 600; text-decoration: none; }
.skip:focus { top: 0.6rem; }

/* Device icons, at the size of the text beside them. Inline-block, because a stylesheet that
   sets svg to block would otherwise stack them on their own lines. The gap after one is a
   written space, never a margin: development annotates every partial with comments and
   newlines, so a margin there would read as a double gap that production does not have. */
.dev-ico { display: inline-block; width: 1.15em; height: 1.15em; vertical-align: -0.2em; margin: 0;
  color: var(--ink); flex: none; }

/* The lockup: the mark at the wordmark's cap height, a third of a cap height between them. The
   mark's drawing is 21 by 15 of its 24 box and Instrument Sans' capitals are 0.72em, so the box
   is 1.152em, its 1.5-unit side padding is pulled back to the lockup's edge, and the right
   margin is the third of a cap height less that padding and the D's side bearing, so the gap
   is measured ink to ink (the numbers are in shared/_lockup). With
   line-height 1 the wordmark's box is centered on its capitals, so centering lines them up. */
.lockup { display: inline-flex; align-items: center; line-height: 1; white-space: nowrap; }
.lockup .glyph { width: 1.152em; height: 1.152em; margin: 0 0.106em 0 -0.072em; flex: none; color: var(--ink); }
.wordmark { font: 600 1em/1 var(--sans); letter-spacing: -0.02em; color: var(--ink); }

/* Masthead ----------------------------------------------------------------------------- */
.mk-bar { position: sticky; top: 0; z-index: 30; border-bottom: 1px solid var(--hair);
  background: color-mix(in srgb, var(--desk) 90%, transparent);
  -webkit-backdrop-filter: blur(12px) saturate(1.2); backdrop-filter: blur(12px) saturate(1.2); }
.mk-bar .mk-wrap { display: flex; align-items: center; gap: 1.5rem; height: 64px; }
.mk-brand { font-size: 22px; text-decoration: none; color: var(--ink); display: inline-flex; padding: 0.4rem 0; }
.mk-nav { margin-left: auto; display: flex; align-items: center; gap: 1.6rem; }
.mk-nav a { font-size: 15px; font-weight: 550; color: var(--ink-2); text-decoration: none; position: relative; padding: 0.4rem 0; white-space: nowrap; }
.mk-nav a::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0.1rem; height: 1.5px; background: var(--moss);
  transform: scaleX(0); transform-origin: right; transition: transform 0.4s var(--ease); }
.mk-nav a:hover, .mk-nav a.on { color: var(--ink); }
.mk-nav a:hover::after, .mk-nav a.on::after { transform: scaleX(1); transform-origin: left; }
.mk-nav .mk-btn::after, .mk-nav .mk-who::after { display: none; }
.mk-nav .mk-btn { min-height: 38px; padding: 0 1rem; font-size: 14.5px; }
/* A button in the nav keeps its own colors: `.mk-nav a` is more specific than `.mk-btn` and
   painted the Decks button's label in the link gray on its ink fill (unreadable, 2026-10-23). */
.mk-nav a.mk-btn { color: var(--on-ink); }
.mk-nav a.mk-btn.go { color: var(--on-moss); }
.mk-nav a.mk-btn.quiet { color: var(--ink); }
/* The signed-in chip: the nav has to answer "who am I" without being clicked. It is the
   settings link as well, which is where a name normally goes. */
.mk-who { display: inline-flex; align-items: center; gap: 0.5rem; }
.mk-ini { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 50%;
  background: var(--ink); color: var(--on-ink); font: 650 11px/1 var(--sans); letter-spacing: 0.02em; }
.mk-who:hover .mk-ini, .mk-who.on .mk-ini { background: var(--moss); color: var(--on-moss); }
.mk-name { font-size: 15px; }

/* The account end of the bar: the chip that opens the menu (Settings is in it). The chip
   is a button now; it reads like the nav's links, not like a form control. */
.mk-acct { position: relative; display: inline-flex; align-items: center; gap: 0.9rem; flex: 0 0 auto; }
.app-bar .app-nav { margin-left: auto; }
.mk-who { border: 0; background: none; padding: 0.25rem 0; cursor: pointer; color: var(--ink-2);
  font: 550 15px/1 var(--sans); white-space: nowrap; }
.mk-who:hover, .mk-who[aria-expanded="true"] { color: var(--ink); }
.mk-who[aria-expanded="true"] .mk-ini { background: var(--moss); color: var(--on-moss); }
.mk-caret { width: 1em; height: 1em; transition: transform 0.2s var(--ease); }
.mk-who[aria-expanded="true"] .mk-caret { transform: rotate(180deg); }
.mk-acct .mk-menu a::after { display: none; }
.mk-acct .mk-menu a { position: static; padding: 0; }
.mk-acct .mk-menu a { padding: 0 0.75rem; }
/* As wide as the address it names: an ordinary email never wraps (Derick, 2026-10-23, on
   hitchcock.derick+holden@gmail.com breaking over two lines). */
.mk-menu { position: absolute; right: 0; top: calc(100% + 10px); z-index: 40; width: max-content; min-width: 15rem; max-width: min(28rem, calc(100vw - 32px));
  padding: 0.4rem; border: 1px solid var(--hair); border-radius: 10px; background: var(--card);
  box-shadow: 0 12px 32px color-mix(in srgb, var(--ink) 16%, transparent); }
.mk-menu[hidden] { display: none; }
.mk-menu-who { margin: 0; padding: 0.6rem 0.75rem 0.7rem; border-bottom: 1px solid var(--hair); margin-bottom: 0.3rem;
  font-size: 13px; color: var(--ink-2); }
.mk-menu-who b { display: block; margin-top: 0.15rem; color: var(--ink); font-weight: 600; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.mk-acct .mk-menu a, .mk-menu button { display: flex; width: 100%; align-items: center; min-height: 40px; padding: 0 0.75rem;
  border: 0; border-radius: 6px; background: none; color: var(--ink); font: 550 15px/1 var(--sans); text-align: left; cursor: pointer; }
.mk-menu a:hover, .mk-menu button:hover, .mk-menu a:focus-visible, .mk-menu button:focus-visible { background: color-mix(in srgb, var(--ink) 7%, transparent); }
.mk-menu form { margin: 0; }

/* A snapshot page draws both ends; the deckist_who cookie picks one before paint. */
.when-in { display: none; }
.when-out { display: contents; }
html.signed-in .when-in { display: contents; }
html.signed-in .when-out { display: none; }
/* An element that is only for a visitor and keeps its own box (a nav link): hidden for a
   member, otherwise left alone. */
html.signed-in .out-only { display: none; }
.auth-pair { margin-top: 1.4rem; width: 100%; }

/* The marketing bar drops its links on a phone (the footer carries them), and so does the app's
   bar when nobody is signed in. Signed in, the row stays and scrolls in its own box instead, so the page never scrolls sideways: hiding
   them left the signed-in nav as a lone Sign Out button with no way to reach a deck. */
@media (max-width: 760px) {
  .mk-nav { gap: 1.1rem; }
  .mk-nav > a:not(.mk-btn) { display: none; }
  .mk-bar.app-bar .mk-wrap { height: auto; flex-wrap: wrap; gap: 0.5rem 1rem; padding: 0.7rem 0 0.55rem; }
  .app-nav { margin-left: 0; width: 100%; gap: 1.25rem; overflow-x: auto; overscroll-behavior-x: contain;
    scrollbar-width: none; padding-bottom: 0.1rem; }
  .app-nav::-webkit-scrollbar { display: none; }
  .app-nav > a:not(.mk-btn) { display: inline-flex; flex: 0 0 auto; }
  .app-bar .mk-acct { order: 1; margin-left: auto; }
  .app-bar .app-nav { order: 2; }
  .app-nav .mk-name { display: none; }
  /* Sign Out sat 69px off a 390px screen in a row that scrolls with no sign of it; Settings
     has its own Sign out link, and the account chip is the way there, so it gets a
     thumb-sized target. Signed out, the two buttons stay. */
  .mk-acct .mk-who { min-width: 44px; min-height: 44px; justify-content: center; }
  .mk-acct .mk-name { display: none; }
  .mk-nav .when-in .mk-btn { display: none; }
}

/* Buttons: ink is the primary fill, the moss is Start Free, quiet is an outline. ------------- */
.mk-btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; min-height: 46px;
  padding: 0 1.25rem; border: 1px solid var(--ink); border-radius: 7px; background: var(--ink); color: var(--on-ink);
  font: 600 15.5px/1 var(--sans); letter-spacing: -0.005em; text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: background-color 0.25s var(--ease), border-color 0.25s var(--ease), color 0.25s var(--ease), transform 0.25s var(--ease); }
.mk-btn:hover { background: color-mix(in srgb, var(--ink) 84%, var(--card)); border-color: transparent; transform: translateY(-1px); }
.mk-btn:active { transform: none; }
.mk-btn.go { background: var(--moss); border-color: var(--moss); color: var(--on-moss); }
.mk-btn.go:hover { background: var(--moss-hover); border-color: var(--moss-hover); }
.mk-btn.quiet { background: transparent; color: var(--ink); border-color: color-mix(in srgb, var(--ink) 26%, transparent); }
.mk-btn.quiet:hover { background: var(--card); border-color: color-mix(in srgb, var(--ink) 50%, transparent); }
.mk-btn.wide { width: 100%; }
/* Two buttons that sit together share one width, the wider label's (catalog A1). */
.pair-eq { display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 0.6rem; }
.pair-eq > * { min-width: 0; }
.pair-eq > form { display: grid; margin: 0; }
.pair-eq .mk-btn, .pair-eq .btn { width: 100%; }
.mk-nav .pair-eq { gap: 0.55rem; }

/* Sections: a heading in the serif on the desk, a hairline under it, the content on cards. */
.sec { padding: clamp(2.8rem, 5.4vw, 4.8rem) 0; scroll-margin-top: 4rem; }
.sec.page-top { padding-top: clamp(2.2rem, 4.2vw, 3.3rem); }
.sec-head { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); gap: 0.9rem 3.5rem; align-items: end;
  padding-bottom: 1.4rem; margin-bottom: clamp(1.4rem, 2.6vw, 2rem); border-bottom: 1px solid var(--hair); }
.sec-head > * { min-width: 0; }
.sec-head h1, .sec-head h2 { font-size: clamp(1.8rem, 1.1rem + 2.9vw, 3.25rem); }
.pricing .sec-head h1 { font-size: clamp(2.4rem, 1.6rem + 2.8vw, 3.7rem); }
.sec-head p { margin: 0; font-size: clamp(1.02rem, 0.98rem + 0.2vw, 1.12rem); max-width: 34rem; }
@media (max-width: 880px) { .sec-head { grid-template-columns: minmax(0, 1fr); } }

.cards2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; align-items: stretch; }
.cards2 > * { min-width: 0; }
@media (max-width: 760px) { .cards2 { grid-template-columns: minmax(0, 1fr); } }
.note-card { background: var(--card); border: 1px solid var(--hair); border-radius: var(--radius);
  padding: clamp(1.35rem, 2.4vw, 1.9rem) clamp(1.35rem, 2.6vw, 2.1rem); }
.note-card h3 { font-size: clamp(1.3rem, 1.15rem + 0.5vw, 1.55rem); margin: 0 0 0.6rem; }
.note-card p { margin: 0; }
.note-card p + p { margin-top: 0.7em; }
.after-cards { margin: 1.1rem 0 0; font-size: 15px; }

/* Hero ---------------------------------------------------------------------------------- */
.hero { padding: clamp(2.2rem, 4.2vw, 3.3rem) 0 clamp(1.9rem, 3vw, 2.4rem); }
.lead-in { margin: 0 0 1.1rem; font-size: 15.5px; font-weight: 550; color: var(--ink-2); }
.hero h1 { font-size: clamp(2.7rem, 1.2rem + 4.6vw, 4.8rem); line-height: 1.02; letter-spacing: -0.02em; }
.mk h1 em { font-style: italic; font-weight: 450; color: var(--moss); letter-spacing: -0.01em; }
.hero-row { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr); gap: 1.3rem clamp(2rem, 5vw, 5rem);
  align-items: start; margin-top: clamp(1.3rem, 2.4vw, 1.9rem); }
.hero-row > * { min-width: 0; }
.lede { margin: 0; max-width: 38rem; font-size: clamp(1.06rem, 1rem + 0.3vw, 1.2rem); line-height: 1.55; color: var(--ink-2); }
.cta { display: flex; flex-wrap: wrap; gap: 0.7rem; }
.cta-note { margin: 1rem 0 0; font-size: 15px; color: var(--ink-2); }
/* A pair that is also a flex row (.cta, a price card's actions) stays a pair at one width. */
.cta.pair-eq, .price .actions.pair-eq { display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr; }
/* On a phone, where two at that width do not fit, they stack at the full width. */
@media (max-width: 560px) {
  .cta.pair-eq, .price .actions.pair-eq { display: grid; grid-auto-flow: row; width: 100%; align-self: stretch; }
}
@media (max-width: 900px) { .hero-row { grid-template-columns: minmax(0, 1fr); } }

/* The box: the hero's proof. Two devices, each a card you flip and rate, and between them the
   box both of them file into, with the record under it. ----------------------------------- */
.boxsec { padding: 0 0 clamp(1.4rem, 3vw, 2.6rem); scroll-margin-top: 4rem; }
.box-head { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.5rem 2.2rem; margin: 0 0 1.15rem; }
.box-head h2 { font-size: clamp(1.6rem, 1.3rem + 1vw, 2.1rem); }
.box-head p { margin: 0; font-size: 15.5px; line-height: 1.45; }

/* On a desk wide enough, each device's label, card and keys sit on one subgrid with the box
   between them: the box is exactly as tall as a label and a card, and the record starts level
   with the keys. */
.demo { display: grid; grid-template-columns: minmax(0, 17rem) minmax(0, 1fr) minmax(0, 17rem); grid-template-rows: auto auto auto;
  gap: 0.7rem 1.5rem; }
.demo > * { min-width: 0; }
.dev { grid-row: 1 / span 3; display: grid; grid-template-rows: subgrid; }
.dev[data-device="phone"] { grid-column: 1; }
.dev[data-device="mac"] { grid-column: 3; }
.boxwrap { display: contents; }
.box { grid-column: 2; grid-row: 1 / span 2; }
.record { grid-column: 2; grid-row: 3; align-self: start; }
.dev-top { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; margin: 0; font-size: 14.5px; }
.dev-name { display: inline-flex; align-items: center; gap: 0.4rem; font-weight: 600; color: var(--ink); }
.dev-name .dev-ico { width: 1.3em; height: 1.3em; margin: 0; vertical-align: 0; }
.dev-clock { color: var(--muted); white-space: nowrap; }

/* The card: two faces in one grid cell, so the cell takes the taller face and nothing is
   positioned absolutely. rotateX turns it over the way a card on a desk turns. */
.flip { display: grid; perspective: 1100px; cursor: pointer; }
.flip-in { display: grid; transform-style: preserve-3d; transition: transform 0.8s var(--ease); }
.side { grid-area: 1 / 1; -webkit-backface-visibility: hidden; backface-visibility: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.45rem;
  min-height: 10.75rem; padding: 1.5rem 1.1rem 1.2rem; text-align: center;
  background: var(--card); border: 1px solid var(--hair); border-radius: var(--radius); }
.side.back { transform: rotateX(180deg); }
.dev.flipped .flip-in { transform: rotateX(180deg); }
.side .q { margin: 0; font: 500 1.35rem/1.22 var(--serif); letter-spacing: -0.012em; color: var(--ink); text-wrap: balance; }
.side .qs { margin: 0; font: 400 0.92rem/1.3 var(--serif); color: var(--muted); text-wrap: balance; }
.side .a { margin: 0; font: 500 1.3rem/1.25 var(--serif); color: var(--ink); text-wrap: balance; }
.side .rule { display: block; width: 2.4rem; height: 1px; background: var(--hair); }

/* The reveal button and the four keys share one cell, so swapping them moves nothing below. */
.slot { display: grid; align-self: start; }
.slot > * { grid-area: 1 / 1; }
.slot [hidden] { display: none; }
.slot .show { width: 100%; min-height: 50px; }
.rate { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.35rem; }
.rate button { min-height: 50px; padding: 0.35rem 0.15rem; border: 1px solid var(--hair); border-radius: 7px; background: var(--card);
  font: 650 14px/1.1 var(--sans); cursor: pointer; display: grid; place-content: center; justify-items: center; gap: 0.18rem;
  transition: border-color 0.2s var(--ease), background-color 0.2s var(--ease), transform 0.15s var(--ease); }
.rate button small { font-size: 11.5px; font-weight: 550; color: var(--muted); white-space: nowrap; }
.rate button:active { transform: scale(0.97); }
.rate [data-r="again"] { color: var(--again); } .rate [data-r="again"]:hover { border-color: var(--again); }
.rate [data-r="hard"] { color: var(--hard); } .rate [data-r="hard"]:hover { border-color: var(--hard); }
.rate [data-r="good"] { color: var(--good); } .rate [data-r="good"]:hover { border-color: var(--good); }
.rate [data-r="easy"] { color: var(--easy); } .rate [data-r="easy"]:hover { border-color: var(--easy); }

/* The box itself: a tray a shade below the desk with a front wall, seven compartments, each
   behind a divider card whose tab says when its cards come back, and the cards standing in
   them as slips. */
.box { --lip: color-mix(in srgb, var(--desk-2) 84%, var(--ink));
  list-style: none; margin: 0; padding: 0.65rem 0.45rem 0.5rem; display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  background: var(--desk-2); border: 1px solid var(--hair); border-bottom: 8px solid var(--lip); border-radius: 12px 12px 10px 10px;
  min-height: 12.5rem; }
.comp { display: flex; flex-direction: column; min-width: 0; padding: 0 0.28rem; }
.comp + .comp { border-left: 1px solid var(--hair-soft); }
.tab { align-self: center; position: relative; z-index: 1; padding: 0.3rem 0.6rem 0.32rem; background: var(--card);
  border: 1px solid var(--hair); border-bottom: 0; border-radius: 6px 6px 0 0;
  font: 600 12px/1.15 var(--sans); color: var(--ink-2); white-space: nowrap; }
/* The divider's top edge, which the tab stands on, runs the width of its compartment. */
.slips { list-style: none; margin: 0; padding: 0.5rem 0 0.35rem; display: grid; gap: 0.35rem; align-content: start; flex: 1;
  border-top: 3px solid var(--card); box-shadow: 0 -1px 0 var(--hair); }
.slip { background: var(--card); border: 1px solid var(--hair); border-radius: 5px; padding: 0.38rem 0.3rem;
  font: 500 13px/1.2 var(--serif); color: var(--ink); text-align: center; white-space: nowrap; }
.slip.new { background: var(--moss-soft); border-color: color-mix(in srgb, var(--moss) 45%, transparent); }
.slip.flying { position: relative; z-index: 8; box-shadow: var(--lift); }
/* Point at a card in the box and the entries that filed it light in the record, and the other
   way round: the compartment is read off the record, and this shows which part of it. */
.slip { cursor: default; transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease); }
.slip:focus-visible { outline-offset: 2px; }
.slip.lit, .record li.lit { background: color-mix(in srgb, var(--moss) 16%, var(--card)); border-color: color-mix(in srgb, var(--moss) 55%, transparent); }
.record li { transition: background-color 0.2s var(--ease); }

/* The record: the union of both devices' answers, in time order, newest at the foot. */
.record { background: var(--card); border: 1px solid var(--hair); border-radius: var(--radius); padding: 0.85rem 1.05rem 0.9rem; }
.record-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin: 0 0 0.35rem; }
.record-head h3 { font-size: 1.1rem; }
.record-head span { font-size: 14px; color: var(--muted); }
.record ol { list-style: none; margin: 0; padding: 0; min-height: 9.6rem; }
.record li { display: grid; grid-template-columns: 4.8rem 5.6rem minmax(0, 1fr) 3.4rem; gap: 0.7rem; align-items: center;
  padding: 0.45rem 0.55rem; border-top: 1px solid var(--hair-soft); font-size: 14px; border-radius: 6px; }
.record li:first-child { border-top-color: transparent; }
.record li .t { color: var(--muted); white-space: nowrap; }
.record li .d { display: inline-flex; align-items: center; gap: 0.35rem; color: var(--ink-2); white-space: nowrap; }
.record li .d .dev-ico { margin: 0; vertical-align: 0; color: var(--ink-2); }
.record li .c { font: 500 15px/1.25 var(--serif); color: var(--ink); white-space: nowrap; }
.record li .c .tag { display: none; }
.record li .r { font-weight: 650; text-align: right; white-space: nowrap; }
.record li .r.again { color: var(--again); } .record li .r.hard { color: var(--hard); }
.record li .r.good { color: var(--good); } .record li .r.easy { color: var(--easy); }
.record li.new { background: var(--moss-soft); border-top-color: transparent; }
.record-foot { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.2rem 1rem; margin: 0.5rem 0 0; padding-top: 0.65rem;
  border-top: 1px solid var(--hair); font-size: 14px; color: var(--ink-2); }
.record-foot b { color: var(--ink); font-weight: 650; }
.demo-note { margin: 1.2rem 0 0; font-size: 15px; max-width: 62rem; }

/* Two devices side by side over the box, below a desk wide enough for three columns. */
@media (max-width: 1179px) {
  .demo { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: none; gap: 1.1rem 1.25rem; }
  .dev { grid-row: 1; grid-template-rows: none; gap: 0.7rem; align-self: start; }
  .dev[data-device="mac"] { grid-column: 2; }
  .boxwrap { display: grid; gap: 1rem; grid-column: 1 / -1; grid-row: 2; }
  .box, .record { grid-column: auto; grid-row: auto; }
}
@media (max-width: 759px) {
  .demo { gap: 0.9rem 0.7rem; }
  .side { min-height: 8.25rem; padding: 1.1rem 0.75rem 0.9rem; }
  .side .q { font-size: 1.12rem; }
  .side .a { font-size: 1.1rem; }
  .rate { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Two rows of keys are taller than the button they replace; the slot keeps their height
     either way, so turning a card over moves nothing under it. */
  .slot { min-height: calc(100px + 0.35rem); align-content: start; }
  .dev-top { font-size: 14px; }
  /* On a phone the box turns on its side: one compartment a row, the divider's tab at the left. */
  .box { grid-template-columns: minmax(0, 1fr); padding: 0.45rem 0.6rem 0.45rem 0.55rem; min-height: 0; }
  .comp { flex-direction: row; align-items: center; padding: 0.3rem 0; min-height: 2.9rem; }
  .comp + .comp { border-left: 0; border-top: 1px solid var(--hair-soft); }
  .tab { flex: 0 0 5.4rem; align-self: center; text-align: left; border: 1px solid var(--hair); border-right: 0; border-radius: 6px 0 0 6px; padding: 0.42rem 0.55rem; }
  .slips { display: flex; flex-wrap: wrap; align-self: stretch; align-content: center; gap: 0.35rem; padding: 0.15rem 0 0.15rem 0.55rem;
    border-top: 0; box-shadow: none; border-left: 3px solid var(--card); }
  .slip { padding: 0.32rem 0.6rem; }
  .record { padding: 0.75rem 0.7rem 0.8rem; }
  .record li { grid-template-columns: 4.5rem 1.3rem minmax(0, 1fr) 3.1rem; gap: 0.5rem; padding: 0.45rem 0.35rem; }
  .record li .d .nm { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .record li .c .q { display: none; }
  .record li .c .tag { display: inline; }
}

/* FSRS, fitted: the facts on the desk, one card's intervals drawn to scale on a card. */
.fit-grid { display: grid; grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr); gap: 2rem clamp(2rem, 5vw, 4.5rem); align-items: start; }
.fit-grid > * { min-width: 0; }
@media (max-width: 960px) { .fit-grid { grid-template-columns: minmax(0, 1fr); } }
.fit-copy h2 { font-size: clamp(1.8rem, 1.1rem + 2.9vw, 3.25rem); padding-bottom: 1.3rem; margin-bottom: 1.2rem; border-bottom: 1px solid var(--hair); }
.fit-intro { margin: 0 0 1.8rem; font-size: clamp(1.02rem, 0.98rem + 0.2vw, 1.12rem); max-width: 34rem; }
.desk-facts { display: grid; gap: 1.6rem; }
.desk-facts h3 { font-size: clamp(1.25rem, 1.15rem + 0.4vw, 1.45rem); margin: 0 0 0.45rem; }
.desk-facts p { margin: 0; max-width: 36rem; }
.chart-card h3 { font-size: 1.3rem; margin: 0 0 0.35rem; }
.chart-card > p { margin: 0 0 1.1rem; font-size: 15px; }
.ivs { width: 100%; border-collapse: collapse; font-size: 15px; }
.ivs th, .ivs td { text-align: left; padding: 0.62rem 0.75rem 0.62rem 0; border-bottom: 1px solid var(--hair-soft); white-space: nowrap; vertical-align: middle; }
.ivs thead th { font: 600 13px/1.3 var(--sans); color: var(--muted); border-bottom-color: var(--hair); }
.ivs tbody tr:last-child td { border-bottom: 0; }
.ivs td.r { font-weight: 650; width: 5.2rem; }
.ivs td.r.good { color: var(--good); } .ivs td.r.again { color: var(--again); } .ivs td.r.easy { color: var(--easy); }
.ivs td.iv { width: 5.4rem; color: var(--ink); }
.ivs td.b { width: 100%; padding-right: 0; }
/* The forty-day bar fills the column and every other bar is the same fraction of it, so the
   scale holds at every width and nothing pushes the table past a phone's edge. */
.ivbar { display: block; width: calc(var(--days) / 40 * 100%); min-width: 6px; height: 9px; border-radius: 2px; background: currentColor; }
.ivs tr.good .ivbar { color: var(--good); } .ivs tr.again .ivbar { color: var(--again); } .ivs tr.easy .ivbar { color: var(--easy); }
.devs-row { display: flex; gap: 0.6rem; margin: 0 0 0.6rem; }
.devs-row .dev-ico { width: 1.6rem; height: 1.6rem; margin: 0; }

/* Price: two cards that share a height and a width. ----------------------------------------- */
.prices { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; align-items: stretch; }
.prices > * { min-width: 0; }
@media (max-width: 760px) { .prices { grid-template-columns: minmax(0, 1fr); } }
.price { display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--hair); border-radius: var(--radius);
  padding: clamp(1.4rem, 2.6vw, 2.2rem) clamp(1.35rem, 2.6vw, 2.2rem); }
.price .what { margin: 0 0 0.9rem; font: 600 15px/1.3 var(--sans); color: var(--ink); }
.amount { margin: 0; font: 500 clamp(3.1rem, 2.4rem + 2.6vw, 4.5rem)/1 var(--serif); letter-spacing: -0.03em; color: var(--ink); }
.per { display: block; margin: 0.65rem 0 0; font-size: 15.5px; color: var(--ink-2); }
.price ul { list-style: none; padding: 0; margin: 1.4rem 0 1.3rem; display: grid; gap: 0.55rem; }
/* The list marker is a card: a tiny filled tile in the moss, the way the box files a card. An
   outlined one read as an unchecked checkbox in the cold review. */
.price li { position: relative; padding-left: 1.65rem; color: var(--ink-2); font-size: 15.5px; line-height: 1.45; }
.price li::before { content: ""; position: absolute; left: 0.1rem; top: 0.5em; width: 0.75rem; height: 0.5rem;
  background: var(--moss); border-radius: 2px; }
.price .foot { margin: 0; font-size: 14.5px; color: var(--ink-2); }
.price .foot + .foot { margin-top: 0.5rem; }
.price .actions { margin-top: auto; padding-top: 1.4rem; display: flex; flex-wrap: wrap; gap: 0.6rem; }
.price .actions.pair-eq { align-self: flex-start; }
.price .actions form { margin: 0; display: inline-flex; }
.price .req { margin: 0.6rem 0 0; font-size: 14px; color: var(--ink-2); flex-basis: 100%; }
.price-fine { margin: 1.2rem 0 0; font-size: 15px; max-width: 62rem; }
.price-fine + .price-fine { margin-top: 0.6rem; }

/* News: the last thing on the page, above the footer, on a card of its own. ------------------ */
.news-card { display: grid; grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr); gap: 1.5rem clamp(2rem, 5vw, 4.5rem); align-items: center;
  background: var(--card); border: 1px solid var(--hair); border-radius: 14px; padding: clamp(1.5rem, 3.4vw, 2.6rem); }
.news-card > * { min-width: 0; }
.news-card h2 { font-size: clamp(1.8rem, 1.4rem + 1.4vw, 2.5rem); margin: 0 0 0.6rem; }
.news-card p { margin: 0; }
.news-card .early-note { margin-top: 0.7rem; }
@media (max-width: 860px) { .news-card { grid-template-columns: minmax(0, 1fr); } }
.early { scroll-margin-top: 6rem; }
.early-form { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.6rem; align-items: stretch; }
@media (max-width: 520px) { .early-form { grid-template-columns: minmax(0, 1fr); } }
.early-form input[type="email"] { height: 48px; font-size: 16px; }
.early-form .mk-btn { min-height: 48px; }
/* The honeypot. Out of sight and out of the tab order, filled only by a bot. */
.early-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
/* The address a held sign-up will hear at: its own line, broken anywhere only when a phone is
   narrower than the address (an address has no spaces to wrap at). */
.received-email { display: block; margin: 0.35rem 0; font-weight: 600; color: var(--ink); overflow-wrap: anywhere; }
.early-note { margin: 0.75rem 0 0; font-size: 14px; color: var(--ink-2); }
.early-msg { margin: 0.7rem 0 0; font-size: 14.5px; color: var(--again); }
.early-done { display: flex; gap: 0.7rem; align-items: flex-start; margin: 0; font-size: 1.05rem; line-height: 1.5; color: var(--ink-2);
  animation: early-in 0.4s var(--ease) both; }
.early-done strong { color: var(--ink); font-weight: 650; }
.early-done svg { flex: 0 0 auto; width: 1.35em; height: 1.35em; margin-top: 0.1em; color: var(--moss); }
@keyframes early-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* Documents: Why, Privacy, Terms, Support. The heading on the desk, held beside the text, and
   the text on one card, both from the content's left edge. ------------------------------------ */
.doc { padding: clamp(2.2rem, 4.2vw, 3.3rem) 0 clamp(3rem, 6vw, 5rem); }
.doc-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 46rem); gap: 1.4rem clamp(2.5rem, 6vw, 6rem); align-items: start; }
.doc-grid > * { min-width: 0; }
.doc-head { position: sticky; top: 6.2rem; }
.doc-head h1 { font-size: clamp(2.3rem, 1.75rem + 1.5vw, 2.95rem); line-height: 1.06; }
/* The heading needs about 21rem beside a 46rem card; below that the two stack. */
@media (max-width: 1259px) { .doc-grid { grid-template-columns: minmax(0, 46rem); } .doc-head { position: static; } }
.doc-head .stamp { margin: 0.8rem 0 0; font-size: 15px; color: var(--ink-2); }
.doc-head .lede { margin: 1rem 0 0; }
.doc-card { background: var(--card); border: 1px solid var(--hair); border-radius: 14px; padding: clamp(1.4rem, 4.4vw, 3rem); }
.doc-card h2 { font-size: clamp(1.35rem, 1.25rem + 0.4vw, 1.6rem); margin: 2.1rem 0 0.55rem; line-height: 1.15; }
.doc-card h2:first-child { margin-top: 0; }
.doc-card p, .doc-card li { color: var(--ink-2); font-size: 16.5px; line-height: 1.65; }
.doc-card p:last-child { margin-bottom: 0; }
.doc-card strong { color: var(--ink); font-weight: 650; }
.doc-card ul { padding-left: 1.2rem; }
.doc-foot { margin: 1.4rem 0 0; font-size: 15.5px; }

/* The auth card: one card, centered on the desk. -------------------------------------------- */
.mk .auth-wrap { max-width: 27rem; margin: clamp(1.4rem, 5vh, 3.6rem) auto 0; }
.mk .auth-card { padding: clamp(1.4rem, 4.4vw, 2.2rem); border-radius: 14px; }
.mk .auth-title { font-size: clamp(2.2rem, 1.9rem + 1.2vw, 2.7rem); line-height: 1.05; margin: 0 0 1.1rem; }
.mk .auth-card form .mk-btn { margin-top: 0.4rem; }

/* The web client on the same desk ------------------------------------------------------- */
.mk.app .app-main { padding: clamp(1.6rem, 3vw, 2.4rem) 0 5rem; flex: 1; }
.mk.app h1 em { font-style: italic; }
.mk-flash { margin: 1.2rem 0 0; }

/* The admin list: rows on a card, the address first. */
.admin-head { display: flex; align-items: end; justify-content: space-between; gap: 1rem 1.5rem; flex-wrap: wrap; }
.admin-head h1 { font-size: clamp(2.2rem, 1.6rem + 2vw, 3.2rem); }
.signups { width: 100%; border-collapse: collapse; }
.signups th { padding: 0.75rem 1.2rem 0.6rem 0; }
.signups td { padding: 0.7rem 1.2rem 0.7rem 0; color: var(--ink-2); font-size: 15.5px; }
.signups td.when { white-space: nowrap; }

/* Footer ------------------------------------------------------------------------------------ */
.mk-foot { border-top: 1px solid var(--hair); padding: 2.2rem 0 3rem; color: var(--ink-2); font-size: 15px; }
.mk-foot-row { display: flex; flex-wrap: wrap; gap: 0.8rem 1.8rem; align-items: baseline; }
.mk-foot-row nav { display: flex; gap: 0.4rem 1.3rem; flex-wrap: wrap; }
.mk-foot a { color: var(--ink-2); }
.mk-foot a:hover { color: var(--ink); }
.mk-foot .by { color: var(--ink); }
.mk-copy { margin-left: auto; color: var(--ink-2); }
@media (max-width: 760px) { .mk-copy { margin-left: 0; flex-basis: 100%; } }
@media (max-width: 560px) {
  .mk-foot-row { gap: 0.9rem 1.8rem; }
  .mk-foot-row nav { display: grid; grid-template-columns: repeat(3, max-content); gap: 0.55rem 1.5rem; flex-basis: 100%; }
}

/* Reveal: a 14px rise and a 6px blur to sharp, staggered by the layout's script. */
.mk-reveal { opacity: 0; transform: translateY(14px); filter: blur(6px);
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease), filter 0.8s var(--ease); }
.mk-reveal.in { opacity: 1; transform: none; filter: none; }

/* The version panel ("?") is identical in every project and inks itself; here it takes the
   desk's card and faces. body # outranks the partial's own #verpanel rules. */
body #verpanel .vp-card { background: var(--card); color: var(--ink); font: 15px/1.5 var(--sans);
  border: 1px solid var(--hair); border-radius: 12px; box-shadow: var(--lift); }
body #verpanel h2 { font: 500 1.25rem/1.2 var(--serif); color: var(--ink); }
body #verpanel dt, body #verpanel .vp-hint, body #verpanel .vp-x { color: var(--muted); }
body #verpanel code, body #verpanel kbd { font-family: var(--sans); background: var(--card-2); color: var(--ink); }

@media (prefers-reduced-motion: reduce) {
  .mk-reveal { opacity: 1; transform: none; filter: none; transition: none; }
  .flip-in { transition: none; }
  .dev.flipped .flip-in { transform: none; }
  .side.back { transform: none; opacity: 0; transition: opacity 0.25s linear; }
  .side.front { transition: opacity 0.25s linear; }
  .dev.flipped .side.back { opacity: 1; }
  .dev.flipped .side.front { opacity: 0; }
  .mk-btn, .mk-nav a::after, .rate button, .early-done { transition: none; animation: none; }
}
