/* ─────────────────────────────────────────────────────────────────────────
   LOXN — mono, dark. Shared design system for the landing page and the two
   legal pages, so the whole site is one surface instead of three.

   Direction: Swiss discipline in pure monochrome. Strict grid, hairline
   rules instead of cards, one dramatic size jump per view, zero colour.
   The brandmark is the only figure on the page — nothing else decorates.
   ───────────────────────────────────────────────────────────────────────── */

@import url('../fonts/fonts.2.css');

:root {
  color-scheme: dark;

  /* Surfaces — the app's own #0A0A0A page, one step up for panels. */
  --bg:         #0a0a0a;
  --surface:    #121212;
  --surface-2:  #171717;

  /* Hairlines carry the structure here; there are no shadows on dark. */
  --line:       rgba(255, 255, 255, 0.11);
  --line-soft:  rgba(255, 255, 255, 0.06);
  --line-hard:  rgba(255, 255, 255, 0.22);

  --text:       #fafafa;
  --muted:      rgba(255, 255, 255, 0.56);
  --dim:        rgba(255, 255, 255, 0.38);

  /* Theme-flipped extremes. Every hardcoded #fff / #0a0a0a used to live in a
     component; they are tokens now so light mode is a value swap, not a
     rewrite of forty rules. --pure is the far end of the text ramp,
     --invert-* is the reversed pair the primary button and flags are cut from. */
  --pure:       #ffffff;
  --invert-bg:  #ffffff;
  --invert-fg:  #0a0a0a;
  --wash:       rgba(255, 255, 255, 0.022);
  --wash-2:     rgba(255, 255, 255, 0.04);
  --head-bg:    rgba(10, 10, 10, 0.86);
  --skeleton:   rgba(255, 255, 255, 0.07);
  --skeleton-hi:rgba(255, 255, 255, 0.14);

  /* Display face is the system grotesk on purpose: on Apple hardware that is
     SF Pro, the exact face the app uses, so site and app read as one thing. */
  --display: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, 'Helvetica Neue', Arial, sans-serif;
  --body:    'DM Sans', -apple-system, system-ui, sans-serif;
  --mono:    ui-monospace, 'SF Mono', SFMono-Regular, Menlo, monospace;
  --serif:   'DM Serif Display', Georgia, serif;

  /* 1.333 scale, fluid at the top end. */
  --s-xs: 12px;
  --s-sm: 14px;
  --s-base: 16px;
  --s-md: clamp(18px, 1rem + 0.4vw, 21px);
  --s-lg: clamp(24px, 1rem + 1.6vw, 34px);
  --s-xl: clamp(32px, 1rem + 3vw, 54px);
  --s-2xl: clamp(38px, 1rem + 4.2vw, 72px);
  --s-3xl: clamp(44px, 1rem + 5.2vw, 88px);

  --gut: clamp(20px, 5vw, 64px);
  --sec: clamp(80px, 11vw, 168px);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --fast: 180ms;

  --head-h: 64px;
  --z-head: 60;
  --z-float: 70;
  --z-overlay: 90;
}

/* Light theme. Paper, not pure white — a #ffffff page is the flattest,
   most generated-looking surface there is, and the warm tint gives the
   monochrome somewhere to sit. Applied when the visitor has picked light,
   or when they have picked nothing and their OS says light. */
:root[data-theme="light"] { color-scheme: light; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) { color-scheme: light; }
}

:root[data-theme="light"],
:root[data-theme="light"] * {
  --shadow-none: 0;
}

:root[data-theme="light"] {
  --bg:         #f3f2ef;
  --surface:    #eae9e5;
  --surface-2:  #e2e1dc;

  --line:       rgba(10, 10, 10, 0.15);
  --line-soft:  rgba(10, 10, 10, 0.08);
  --line-hard:  rgba(10, 10, 10, 0.30);

  --text:       #12120f;
  --muted:      rgba(10, 10, 10, 0.64);
  --dim:        rgba(10, 10, 10, 0.46);

  --pure:       #000000;
  --invert-bg:  #12120f;
  --invert-fg:  #f3f2ef;
  --wash:       rgba(10, 10, 10, 0.025);
  --wash-2:     rgba(10, 10, 10, 0.05);
  --head-bg:    rgba(243, 242, 239, 0.88);
  --skeleton:   rgba(10, 10, 10, 0.07);
  --skeleton-hi:rgba(10, 10, 10, 0.14);
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg:         #f3f2ef;
    --surface:    #eae9e5;
    --surface-2:  #e2e1dc;

    --line:       rgba(10, 10, 10, 0.15);
    --line-soft:  rgba(10, 10, 10, 0.08);
    --line-hard:  rgba(10, 10, 10, 0.30);

    --text:       #12120f;
    --muted:      rgba(10, 10, 10, 0.64);
    --dim:        rgba(10, 10, 10, 0.46);

    --pure:       #000000;
    --invert-bg:  #12120f;
    --invert-fg:  #f3f2ef;
    --wash:       rgba(10, 10, 10, 0.025);
    --wash-2:     rgba(10, 10, 10, 0.05);
    --head-bg:    rgba(243, 242, 239, 0.88);
    --skeleton:   rgba(10, 10, 10, 0.07);
    --skeleton-hi:rgba(10, 10, 10, 0.14);
  }
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--body);
  font-weight: 300;
  font-size: var(--s-base);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

::selection { background: var(--invert-bg); color: var(--invert-fg); }

a { color: inherit; text-decoration: none; }

:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 3px;
  border-radius: 2px;
}

.wrap { max-width: 1180px; margin: 0 auto; padding: 0 var(--gut); }
.narrow { max-width: 760px; margin: 0 auto; padding: 0 var(--gut); }

/* ── Type ──────────────────────────────────────────────────────────────── */

h1, h2, h3, .display {
  font-family: var(--display);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 0.98;
  text-wrap: balance;
}

h1 { font-size: var(--s-2xl); }
h2 { font-size: var(--s-xl); }
h3 { font-size: var(--s-lg); letter-spacing: -0.025em; }

p { color: var(--muted); max-width: 68ch; }
p + p { margin-top: 1em; }

strong { color: var(--text); font-weight: 400; }

/* The wide-tracked mono eyebrow is the structural motif of the whole site —
   it appears above every section and nowhere else. */
.eyebrow {
  font-family: var(--mono);
  font-size: var(--s-xs);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--dim);
  display: flex;
  align-items: center;
  gap: 10px;
}
.eyebrow::before {
  content: '';
  width: 9px; height: 9px;
  flex: none;
  background: currentColor;
  /* the brandmark, as a clip path — the motif repeated at label scale */
  clip-path: polygon(50% 2%, 55% 45%, 98% 50%, 55% 55%, 50% 98%, 45% 55%, 2% 50%, 45% 45%);
}

.lede { font-size: var(--s-md); color: var(--muted); max-width: 56ch; }

.serif-quote {
  font-family: var(--serif);
  font-weight: 400;
  font-style: italic;
  letter-spacing: -0.01em;
  line-height: 1.25;
  color: var(--text);
}

/* ── Brandmark ─────────────────────────────────────────────────────────── */

/* `fill` must sit on the <svg> itself, not on `.mark path`: the mark is drawn
   through <use>, and a descendant selector cannot reach into its shadow tree.
   `fill` is an inherited property, so it crosses the boundary from here. */
.mark { display: block; flex: none; fill: currentColor; }

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.14em;
  font-family: var(--display);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1;
}
/* The mark stands in for the X — the kit's experimental lockup, used as the
   real logo here. Rotated 45° so it reads as a letterform, not an icon. */
.wordmark .mark { transform: rotate(45deg); }

/* ── Buttons ───────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--s-sm);
  letter-spacing: -0.01em;
  padding: 15px 26px;
  min-height: 48px;
  border: 1px solid transparent;
  border-radius: 2px;
  cursor: pointer;
  transition: transform var(--fast) var(--ease),
              background var(--fast) var(--ease),
              border-color var(--fast) var(--ease),
              color var(--fast) var(--ease);
}

.btn-primary { background: var(--invert-bg); color: var(--invert-fg); }
.btn-primary:hover { background: var(--text); }
.btn-primary:active { background: var(--muted); }

.btn-ghost { border-color: var(--line-hard); color: var(--text); }
.btn-ghost:hover { border-color: var(--text); background: var(--wash-2); }
.btn-ghost:active { background: var(--wash); }

.btn-sm { padding: 10px 18px; min-height: 40px; font-size: var(--s-xs); }

/* Animated underline — colour-only link hovers read as unfinished. */
.ulink { position: relative; color: var(--text); }
.ulink::after {
  content: '';
  position: absolute; left: 0; bottom: -2px;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--fast) var(--ease);
}
.ulink:hover::after { transform: scaleX(1); }

/* ── Header ────────────────────────────────────────────────────────────── */

.site-head {
  position: sticky; top: 0; z-index: 60;
  border-bottom: 1px solid transparent;
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.site-head.scrolled {
  background: var(--head-bg);
  border-bottom-color: var(--line);
}
.head-inner {
  height: 64px;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
}
.head-nav { display: flex; align-items: center; gap: 30px; }
.head-nav a {
  font-size: var(--s-sm);
  color: var(--muted);
  transition: color var(--fast) var(--ease);
}
.head-nav a:hover { color: var(--text); }
@media (max-width: 900px) { .head-nav { display: none; } }

/* ── Sections ──────────────────────────────────────────────────────────── */

section { padding: var(--sec) 0; }
.rule { border: none; border-top: 1px solid var(--line-soft); }

.sec-head { margin-bottom: clamp(40px, 6vw, 76px); }
.sec-head .eyebrow { margin-bottom: 22px; }
.sec-head h2 { max-width: 18ch; }
.sec-head p { margin-top: 20px; }

/* ── Hero ──────────────────────────────────────────────────────────────── */

.hero { padding: clamp(56px, 9vw, 120px) 0 clamp(64px, 9vw, 130px); }
.hero-grid {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(40px, 6vw, 88px);
  align-items: center;
}
@media (max-width: 900px) { .hero-grid { grid-template-columns: 1fr; } }

.hero h1 { font-size: var(--s-3xl); margin: 26px 0 0; }
.hero .lede { margin-top: 26px; }
.hero-cta { margin-top: 38px; display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.hero-note { margin-top: 20px; font-family: var(--mono); font-size: var(--s-xs); color: var(--dim); letter-spacing: 0.04em; }

/* The signature moment: the mark held in a registration frame, the way a
   trademark is presented on a spec sheet. It used to sit in a breathing radial
   glow — that orb is the single most generated-looking thing a dark hero can
   have, so the structure is ruled lines now and there is no gradient, no
   drop-shadow and no ambient animation anywhere on this page. */
.hero-mark {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  width: 100%;
  max-width: 460px;
  margin-inline: auto;
}
/* Crosshair: two hairlines through the centre, stopping short of the frame. */
.hero-mark::before,
.hero-mark::after {
  content: '';
  position: absolute;
  background: var(--line);
}
.hero-mark::before { left: 6%; right: 6%; height: 1px; }
.hero-mark::after  { top: 6%; bottom: 6%; width: 1px; }

.hero-frame {
  position: absolute;
  inset: 12%;
  border: 1px solid var(--line);
}
/* Corner ticks — the frame reads as a measurement, not as a card. */
.hero-frame span {
  position: absolute;
  width: 11px; height: 11px;
  border: 0 solid var(--line-hard);
}
.hero-frame span:nth-child(1) { top: -1px; left: -1px; border-top-width: 1px; border-left-width: 1px; }
.hero-frame span:nth-child(2) { top: -1px; right: -1px; border-top-width: 1px; border-right-width: 1px; }
.hero-frame span:nth-child(3) { bottom: -1px; left: -1px; border-bottom-width: 1px; border-left-width: 1px; }
.hero-frame span:nth-child(4) { bottom: -1px; right: -1px; border-bottom-width: 1px; border-right-width: 1px; }

.hero-mark .mark {
  position: relative;
  width: min(56%, 300px);
  height: auto;
  color: var(--text);
}
.hero-mark .cap {
  position: absolute; left: 12%; bottom: calc(12% - 26px);
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--dim);
}

/* ── Stat strip ────────────────────────────────────────────────────────── */

/* Three equal cells in a row is the shape every generated page uses. The lead
   statistic is the argument of this section, so it gets the scale it deserves
   and the two supporting figures stack beside it. */
.strip {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.strip > div { padding: clamp(26px, 3.4vw, 44px) clamp(18px, 2.4vw, 34px); }
.strip > div:first-child { grid-row: span 2; }
.strip > div + div { border-left: 1px solid var(--line); }
.strip > div:last-child { border-top: 1px solid var(--line); }
.strip .n {
  font-family: var(--display);
  font-weight: 800;
  font-size: var(--s-lg);
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.strip > div:first-child .n { font-size: var(--s-2xl); }
.strip > div:first-child .l { font-size: var(--s-base); max-width: 34ch; }
.strip .l { margin-top: 12px; font-size: var(--s-sm); color: var(--muted); max-width: 30ch; }
.strip .src { margin-top: 12px; font-family: var(--mono); font-size: 11px; color: var(--dim); letter-spacing: 0.04em; }
@media (max-width: 760px) {
  .strip { grid-template-columns: 1fr; }
  .strip > div:first-child { grid-row: auto; }
  .strip > div + div { border-left: none; border-top: 1px solid var(--line); }
}

/* ── Rule-separated feature list (no cards — hairlines do the work) ────── */

.rows { border-top: 1px solid var(--line); }
.row {
  display: grid;
  grid-template-columns: 60px 1fr 1.25fr;
  gap: clamp(16px, 3vw, 48px);
  padding: clamp(26px, 3.2vw, 40px) 0;
  border-bottom: 1px solid var(--line);
  align-items: start;
  transition: background var(--fast) var(--ease);
}
.row:hover { background: var(--wash); }
.row .num { font-family: var(--mono); font-size: var(--s-xs); color: var(--dim); letter-spacing: 0.1em; padding-top: 6px; }
.row h3 { letter-spacing: -0.02em; }
.row p { margin: 0; font-size: var(--s-sm); }
@media (max-width: 820px) {
  .row { grid-template-columns: 40px 1fr; }
  .row p { grid-column: 2; margin-top: 10px; }
}

/* ── Modes: a ruled schedule, not a bento ──────────────────────────────────
   This was a 6-column bento of cards. A bento is the house style of every
   generated landing page there is, and this section had the one thing that
   makes a bento unnecessary: the modes differ by WHEN they act, which is real
   information and can be drawn. Each row carries a 24-hour band showing the
   part of the day that mode covers. */

.modes { border-top: 1px solid var(--line); }
.modes-item {
  display: grid;
  grid-template-columns: 190px 1.25fr 200px;
  gap: clamp(16px, 3vw, 44px);
  padding: clamp(24px, 3vw, 36px) 0;
  border-bottom: 1px solid var(--line);
  align-items: start;
  transition: background var(--fast) var(--ease);
}
.modes-item:hover { background: var(--wash); }
.modes-item .tag {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--dim);
  display: block; padding-top: 7px;
}
.modes-item h3 { letter-spacing: -0.025em; margin-bottom: 12px; }
.modes-item p { font-size: var(--s-sm); margin: 0; }

/* The band. 24 cells, filled ones are ink. Hours are read off the scale
   below it, so the graphic never needs a legend. */
.band { padding-top: 6px; }
.band .track {
  display: grid;
  grid-template-columns: repeat(24, 1fr);
  gap: 1px;
  border: 1px solid var(--line);
  padding: 2px;
}
.band .track i { display: block; height: 12px; background: var(--line-soft); }
.band .track i.on { background: var(--text); }
.band .scale {
  display: flex; justify-content: space-between;
  margin-top: 7px;
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.1em; color: var(--dim);
}
.band .note {
  margin-top: 9px;
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--dim);
}
@media (max-width: 980px) {
  .modes-item { grid-template-columns: 150px 1fr; }
  .modes-item .band { grid-column: 2; margin-top: 18px; max-width: 340px; }
}
@media (max-width: 640px) {
  .modes-item { grid-template-columns: 1fr; gap: 14px; }
  .modes-item .tag { padding-top: 0; }
  .modes-item .band { grid-column: 1; margin-top: 4px; }
}

/* ── Pricing ───────────────────────────────────────────────────────────── */

.plans { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.plan { background: var(--bg); padding: clamp(28px, 3.4vw, 46px); }
.plan.featured { background: var(--surface); }
.plan .price { font-family: var(--display); font-weight: 800; font-size: var(--s-xl); letter-spacing: -0.04em; margin: 14px 0 6px; }
.plan .per { font-family: var(--mono); font-size: var(--s-xs); color: var(--dim); letter-spacing: 0.06em; }
.plan ul { list-style: none; margin: 26px 0 30px; }
.plan li { font-size: var(--s-sm); color: var(--muted); padding: 9px 0 9px 22px; position: relative; border-top: 1px solid var(--line-soft); }
.plan li:first-child { border-top: none; }
.plan li::before {
  content: ''; position: absolute; left: 0; top: 17px;
  width: 8px; height: 8px; background: var(--text);
  clip-path: polygon(50% 2%, 55% 45%, 98% 50%, 55% 55%, 50% 98%, 45% 55%, 2% 50%, 45% 45%);
}
.plan li.off { color: var(--dim); }
.plan li.off::before { background: var(--dim); clip-path: none; height: 1px; top: 21px; }
@media (max-width: 760px) { .plans { grid-template-columns: 1fr; } }

/* Billing. This was three cards in a row wearing "Most popular" and "Best
   value" badges, which is exactly the shape mefju's list calls out. Same three
   real StoreKit products, presented as a table: comparable at a glance, with
   the per-week column doing the work the badges used to fake. */
.billing { border-top: none; }
.bill {
  display: grid;
  grid-template-columns: 150px 130px 1fr auto;
  gap: clamp(12px, 2.4vw, 32px);
  align-items: baseline;
  padding: clamp(18px, 2.2vw, 24px) 0;
  border-bottom: 1px solid var(--line);
  transition: background var(--fast) var(--ease);
}
.bill:first-child { border-top: 1px solid var(--line); }
.bill:hover { background: var(--wash); }
.bill .term { font-family: var(--mono); font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--dim); }
.bill .amt {
  font-family: var(--display); font-weight: 800; font-size: var(--s-lg);
  letter-spacing: -0.04em; font-variant-numeric: tabular-nums;
}
.bill .sub { font-size: var(--s-sm); color: var(--muted); margin: 0; }
.bill .rate {
  font-family: var(--mono); font-size: var(--s-xs); letter-spacing: 0.06em;
  color: var(--dim); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap;
}
.bill .rate b { color: var(--text); font-weight: 400; }
@media (max-width: 820px) {
  .bill { grid-template-columns: 1fr auto; gap: 4px 16px; }
  .bill .term { grid-column: 1; }
  .bill .rate { grid-column: 2; grid-row: 1; }
  .bill .amt { grid-column: 1; }
  .bill .sub { grid-column: 1 / -1; }
}

/* ── FAQ ───────────────────────────────────────────────────────────────── */

.faq { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  list-style: none;
  cursor: pointer;
  padding: clamp(20px, 2.6vw, 30px) 44px clamp(20px, 2.6vw, 30px) 0;
  position: relative;
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--s-md);
  letter-spacing: -0.02em;
  transition: color var(--fast) var(--ease);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--pure); }
.faq summary::after {
  content: '+';
  position: absolute; right: 6px; top: 50%;
  transform: translateY(-50%);
  font-family: var(--mono); font-weight: 400; font-size: 20px; color: var(--dim);
  transition: transform var(--fast) var(--ease);
}
.faq details[open] summary::after { content: '−'; }
.faq .a { padding: 0 0 clamp(22px, 2.6vw, 32px); }
.faq .a p { font-size: var(--s-sm); }

/* ── Final CTA ─────────────────────────────────────────────────────────── */

.cta-band { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); text-align: center; }
.cta-band h2 { font-size: var(--s-2xl); margin-bottom: 26px; }
.cta-band p { margin: 0 auto 34px; }

/* ── Footer ────────────────────────────────────────────────────────────── */

.site-foot { padding: clamp(56px, 7vw, 90px) 0 46px; }
.foot-grid {
  display: grid;
  grid-template-columns: 1.6fr repeat(3, 1fr);
  gap: clamp(28px, 4vw, 56px);
  padding-bottom: 46px;
  border-bottom: 1px solid var(--line-soft);
}
@media (max-width: 820px) { .foot-grid { grid-template-columns: 1fr 1fr; } }
.foot-col h4 {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--dim); font-weight: 400; margin-bottom: 18px;
}
.foot-col a { display: block; font-size: var(--s-sm); color: var(--muted); padding: 5px 0; transition: color var(--fast) var(--ease); }
.foot-col a:hover { color: var(--text); }
/* The wordmark is also an <a> in here — without this it inherits `display:block`
   above, and because `.mark` is a block the three parts stack vertically. */
.foot-col a.wordmark { display: inline-flex; padding: 0; color: var(--text); }
.foot-bottom {
  padding-top: 26px;
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.05em; color: var(--dim);
}

/* ── Legal pages ───────────────────────────────────────────────────────── */

.legal { padding: clamp(56px, 7vw, 96px) 0 clamp(80px, 9vw, 130px); }
.legal h1 { font-size: var(--s-xl); margin-bottom: 14px; }
.legal .meta {
  font-family: var(--mono); font-size: var(--s-xs); letter-spacing: 0.06em; color: var(--dim);
  padding-bottom: 40px; margin-bottom: 44px; border-bottom: 1px solid var(--line);
}
.legal .tldr {
  background: var(--surface);
  border: 1px solid var(--line);
  padding: 26px 30px;
  margin-bottom: 56px;
  font-size: var(--s-sm);
  color: var(--muted);
}
.legal .tldr strong { color: var(--text); }
.legal h2 {
  font-size: var(--s-lg);
  margin: 60px 0 18px;
  padding-top: 26px;
  border-top: 1px solid var(--line-soft);
  display: flex; align-items: baseline; gap: 14px;
}
.legal h2::before {
  content: attr(data-num);
  font-family: var(--mono); font-size: 11px; font-weight: 400;
  letter-spacing: 0.14em; color: var(--dim);
  -webkit-text-fill-color: currentColor;
}
.legal p { font-size: var(--s-sm); margin-bottom: 14px; }
.legal ul { list-style: none; margin: 0 0 18px; }
.legal ul li {
  font-size: var(--s-sm); color: var(--muted);
  padding: 7px 0 7px 22px; position: relative;
}
.legal ul li::before {
  content: ''; position: absolute; left: 0; top: 15px;
  width: 7px; height: 7px; background: var(--dim);
  clip-path: polygon(50% 2%, 55% 45%, 98% 50%, 55% 55%, 50% 98%, 45% 55%, 2% 50%, 45% 45%);
}
.legal a:not(.btn) { color: var(--text); border-bottom: 1px solid var(--line-hard); transition: border-color var(--fast) var(--ease); }
.legal a:not(.btn):hover { border-bottom-color: var(--text); }
.legal code {
  font-family: var(--mono); font-size: 12px;
  background: var(--surface-2); border: 1px solid var(--line-soft);
  padding: 2px 7px; border-radius: 2px; color: var(--text);
}
.legal .facts {
  border: 1px solid var(--line);
  background: var(--surface);
  padding: 22px 26px;
  margin: 24px 0;
  display: grid; grid-template-columns: minmax(140px, 1fr) 2.2fr; gap: 12px 26px;
}
.legal .facts .label {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--dim); padding-top: 3px;
}
.legal .facts .value { font-size: var(--s-sm); color: var(--text); }
@media (max-width: 560px) { .legal .facts { grid-template-columns: 1fr; gap: 4px 0; } }
.legal-foot {
  margin-top: 76px; padding-top: 28px; border-top: 1px solid var(--line);
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 10px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.05em; color: var(--dim);
}

/* ── Scroll reveal ─────────────────────────────────────────────────────── */

[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
[data-reveal].in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; transform: none; transition: none; }
  .hero-mark::before { animation: none; }
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CHROME — the parts that are not the page: skip link, progress, theme,
   search, mobile nav, back-to-top, contact, notice, dialogs.
   All of it monochrome and hairline-ruled like the rest; none of it introduces
   a radius, a shadow or a colour the page didn't already have.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Skip to content ───────────────────────────────────────────────────── */

.skip {
  position: fixed; top: 0; left: 0; z-index: 200;
  transform: translateY(-120%);
  background: var(--invert-bg);
  color: var(--invert-fg);
  font-family: var(--display); font-weight: 600; font-size: var(--s-sm);
  padding: 14px 22px;
  transition: transform var(--fast) var(--ease);
}
.skip:focus-visible { transform: translateY(0); outline-offset: -4px; }

/* ── Scroll progress ───────────────────────────────────────────────────── */

/* Sits on the header's bottom edge. --progress is written by one passive
   rAF-throttled scroll handler; scaleX means no layout work per frame. */
.progress {
  position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: var(--text);
  transform: scaleX(var(--progress, 0));
  transform-origin: left;
  opacity: 0;
  transition: opacity var(--fast) var(--ease);
  pointer-events: none;
}
.site-head.scrolled .progress { opacity: 1; }

/* ── Header, sticky and shrinking ──────────────────────────────────────── */

.head-inner { height: var(--head-h); transition: height var(--fast) var(--ease); }
.site-head.scrolled { --head-h: 56px; }
.head-tools { display: flex; align-items: center; gap: 8px; }

/* Square icon button — the chrome's only repeated shape. */
.ibtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px;
  flex: none;
  background: none;
  border: 1px solid transparent;
  color: var(--muted);
  cursor: pointer;
  transition: color var(--fast) var(--ease),
              background var(--fast) var(--ease),
              border-color var(--fast) var(--ease);
}
.ibtn:hover { color: var(--text); background: var(--wash-2); border-color: var(--line); }
.ibtn:active { background: var(--surface-2); }
.ibtn svg { width: 17px; height: 17px; display: block; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: square; }

/* Search opener reads as a field on desktop and an icon on mobile, because a
   search box you cannot see is a search box nobody uses. */
.search-open {
  display: inline-flex; align-items: center; gap: 10px;
  height: 38px; padding: 0 10px 0 12px;
  background: none;
  border: 1px solid var(--line);
  color: var(--dim);
  font-family: var(--mono); font-size: var(--s-xs); letter-spacing: 0.06em;
  cursor: pointer;
  transition: color var(--fast) var(--ease), border-color var(--fast) var(--ease), background var(--fast) var(--ease);
}
.search-open:hover { color: var(--text); border-color: var(--line-hard); background: var(--wash-2); }
.search-open svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.6; }
.search-open .k {
  border: 1px solid var(--line); padding: 2px 6px; font-size: 10px; letter-spacing: 0.08em;
}
@media (max-width: 1040px) { .search-open .lbl, .search-open .k { display: none; } .search-open { padding: 0; width: 38px; justify-content: center; } }

/* The theme control is a three-state segmented switch, not a two-state flip —
   "follow my system" is a real preference and a plain toggle destroys it. */
.theme-seg { display: inline-flex; border: 1px solid var(--line); height: 38px; }
.theme-seg button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; background: none; border: none; color: var(--dim);
  cursor: pointer;
  transition: color var(--fast) var(--ease), background var(--fast) var(--ease);
}
.theme-seg button + button { border-left: 1px solid var(--line); }
.theme-seg button:hover { color: var(--text); background: var(--wash-2); }
.theme-seg button[aria-pressed="true"] { background: var(--invert-bg); color: var(--invert-fg); }
.theme-seg svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.6; }
@media (max-width: 620px) { .theme-seg button { width: 30px; } }

/* ── Mobile nav ────────────────────────────────────────────────────────── */

.nav-open { display: none; }
@media (max-width: 900px) {
  .nav-open { display: inline-flex; }
  .head-inner > .btn-primary { display: none; }
}

/* Full-screen, large type, staggered entrance. A mobile menu is a design
   moment; a cramped dropdown list is what a template does. */
.mobile-nav {
  position: fixed; inset: 0; z-index: var(--z-overlay);
  background: var(--bg);
  display: flex; flex-direction: column;
  padding: 0 var(--gut) calc(var(--gut) + 20px);
  visibility: hidden; opacity: 0;
  /* visibility is stepped, never interpolated: with `visibility 260ms` in the
     list the panel stays computed-hidden for the whole fade, and a hidden
     element cannot take focus — which broke the keyboard path into this menu.
     Open flips it at 0s; close delays it until the fade has finished. */
  transition: opacity 260ms var(--ease), visibility 0s linear 260ms;
  overflow-y: auto;
}
.mobile-nav[data-open="true"] {
  visibility: visible; opacity: 1;
  transition: opacity 260ms var(--ease), visibility 0s linear 0s;
}
.mobile-nav .m-head { height: var(--head-h); display: flex; align-items: center; justify-content: space-between; flex: none; }
.mobile-nav .m-links { margin-top: clamp(28px, 8vw, 60px); border-top: 1px solid var(--line); }
.mobile-nav .m-links a {
  display: flex; align-items: baseline; gap: 16px;
  padding: clamp(14px, 3.4vw, 22px) 0;
  border-bottom: 1px solid var(--line);
  font-family: var(--display); font-weight: 800;
  font-size: clamp(28px, 9vw, 44px); letter-spacing: -0.035em; line-height: 1;
  color: var(--text);
  opacity: 0; transform: translateY(14px);
  transition: opacity 420ms var(--ease), transform 420ms var(--ease), color var(--fast) var(--ease);
}
.mobile-nav[data-open="true"] .m-links a { opacity: 1; transform: none; }
.mobile-nav .m-links a:hover { color: var(--pure); }
.mobile-nav .m-links a .num { font-family: var(--mono); font-weight: 400; font-size: var(--s-xs); letter-spacing: 0.12em; color: var(--dim); }
.mobile-nav .m-foot { margin-top: auto; padding-top: 34px; display: grid; gap: 12px; }
.mobile-nav .m-foot .btn { width: 100%; }

/* ── Floating rail: back to top + contact ──────────────────────────────── */

.rail {
  position: fixed; right: clamp(14px, 2.4vw, 26px); bottom: clamp(14px, 2.4vw, 26px);
  z-index: var(--z-float);
  display: flex; flex-direction: column; gap: 10px; align-items: flex-end;
}
.rail .fab {
  display: inline-flex; align-items: center; gap: 10px;
  height: 46px; padding: 0 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--text);
  font-family: var(--display); font-weight: 600; font-size: var(--s-sm);
  cursor: pointer;
  opacity: 0; transform: translateY(10px); pointer-events: none;
  transition: opacity 240ms var(--ease), transform 240ms var(--ease),
              background var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.rail .fab[data-show="true"] { opacity: 1; transform: none; pointer-events: auto; }
.rail .fab:hover { background: var(--surface-2); border-color: var(--line-hard); }
.rail .fab:active { background: var(--bg); }
.rail .fab svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: square; }
.rail .fab.icon-only { width: 46px; padding: 0; justify-content: center; }
@media (max-width: 620px) { .rail .fab .lbl { display: none; } .rail .fab { width: 46px; padding: 0; justify-content: center; } }

/* ── Dialogs (search, contact, confirm) ────────────────────────────────── */

/* Native <dialog>: focus trapping, Escape, inert background and top-layer
   stacking all come from the platform instead of 80 lines of JS. */
dialog {
  border: 1px solid var(--line);
  background: var(--bg);
  color: var(--text);
  padding: 0;
  max-width: min(640px, calc(100vw - 2 * var(--gut)));
  width: 100%;
}
dialog::backdrop { background: rgba(0, 0, 0, 0.62); }
:root[data-theme="light"] dialog::backdrop { background: rgba(10, 10, 10, 0.34); }
dialog[open] { animation: dlg-in 240ms var(--ease); }
dialog[open]::backdrop { animation: fade-in 240ms var(--ease); }
@keyframes dlg-in { from { opacity: 0; transform: translateY(10px); } }
@keyframes fade-in { from { opacity: 0; } }

.dlg-head {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 18px 20px; border-bottom: 1px solid var(--line);
}
.dlg-body { padding: 24px 26px 26px; }
.dlg-foot { display: flex; flex-wrap: wrap; gap: 10px; justify-content: flex-end; padding: 0 26px 26px; }

/* Search palette sits high, not centred: results grow downward and a centred
   box jumps the whole dialog every time the list length changes. */
#search-dlg { margin: min(11vh, 90px) auto auto; max-width: min(680px, calc(100vw - 2 * var(--gut))); }
.search-field { display: flex; align-items: center; gap: 12px; padding: 0 18px; border-bottom: 1px solid var(--line); }
.search-field svg { width: 17px; height: 17px; flex: none; fill: none; stroke: var(--dim); stroke-width: 1.6; }
.search-field input {
  flex: 1; min-width: 0;
  background: none; border: none; outline: none;
  color: var(--text);
  font-family: var(--body); font-weight: 300; font-size: var(--s-md);
  padding: 20px 0;
}
.search-field input::placeholder { color: var(--dim); }
.search-results { max-height: min(52vh, 460px); overflow-y: auto; }
.search-results a {
  display: block; padding: 15px 20px;
  border-bottom: 1px solid var(--line-soft);
  transition: background var(--fast) var(--ease);
}
.search-results a:hover,
.search-results a[data-active="true"] { background: var(--wash-2); }
.search-results .r-where { display: block; font-family: var(--mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--dim); }
.search-results .r-title { display: block; font-family: var(--display); font-weight: 600; font-size: var(--s-sm); letter-spacing: -0.01em; margin-top: 7px; }
.search-results .r-snip { display: block; font-size: var(--s-xs); line-height: 1.5; color: var(--muted); margin-top: 5px; max-width: none; }
.search-results mark { background: var(--invert-bg); color: var(--invert-fg); padding: 0 2px; }

/* The two states a search actually has. #15 and #16 of mefju's list live here:
   this is the only real form on the site. */
.search-state { padding: 34px 20px 38px; text-align: center; }
.search-state .st-title { font-family: var(--display); font-weight: 600; font-size: var(--s-md); letter-spacing: -0.02em; }
.search-state .st-body { font-size: var(--s-sm); color: var(--muted); margin: 10px auto 0; max-width: 44ch; }
.search-foot {
  display: flex; flex-wrap: wrap; gap: 6px 18px; justify-content: space-between;
  padding: 12px 20px; border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em; color: var(--dim);
}
.search-foot kbd { font: inherit; border: 1px solid var(--line); padding: 2px 5px; }

/* ── Skeletons ─────────────────────────────────────────────────────────── */

/* Real skeletons match the shape of what is coming, and only appear after a
   beat so an instant result never flashes a loading state at anyone. */
.sk { padding: 15px 20px; border-bottom: 1px solid var(--line-soft); }
.sk span {
  display: block; height: 9px; background: var(--skeleton);
  background-image: linear-gradient(90deg, var(--skeleton), var(--skeleton-hi), var(--skeleton));
  background-size: 220% 100%;
  animation: sk-slide 1.15s linear infinite;
}
.sk span + span { margin-top: 9px; }
.sk .w1 { width: 22%; height: 7px; }
.sk .w2 { width: 62%; height: 12px; }
.sk .w3 { width: 88%; }
@keyframes sk-slide { from { background-position: 120% 0; } to { background-position: -120% 0; } }

/* ── Copy button ───────────────────────────────────────────────────────── */

.copy {
  display: inline-flex; align-items: center; gap: 7px;
  background: none; border: 1px solid var(--line);
  color: var(--muted); cursor: pointer;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  padding: 5px 9px;
  transition: color var(--fast) var(--ease), border-color var(--fast) var(--ease), background var(--fast) var(--ease);
}
.copy:hover { color: var(--text); border-color: var(--line-hard); background: var(--wash-2); }
.copy svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.7; }
.copy[data-done="true"] { color: var(--text); border-color: var(--text); }

/* Section headings offer their own anchor. Hidden until the heading is hovered
   or the button itself is focused, so it never clutters a clean read. */
.anchor {
  border: none; background: none; padding: 4px; margin-left: 10px;
  color: var(--dim); cursor: pointer; vertical-align: middle;
  opacity: 0;
  transition: opacity var(--fast) var(--ease), color var(--fast) var(--ease);
}
.anchor svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.7; }
.sec-head:hover .anchor, .anchor:focus-visible { opacity: 1; }
.anchor:hover { color: var(--text); }
@media (hover: none) { .anchor { opacity: 1; } }

/* ── Toast ─────────────────────────────────────────────────────────────── */

.toast {
  position: fixed; left: 50%; bottom: 26px; z-index: 210;
  transform: translate(-50%, 16px);
  background: var(--invert-bg); color: var(--invert-fg);
  font-family: var(--display); font-weight: 600; font-size: var(--s-sm);
  padding: 12px 20px;
  opacity: 0; pointer-events: none;
  transition: opacity 200ms var(--ease), transform 200ms var(--ease);
}
.toast[data-show="true"] { opacity: 1; transform: translate(-50%, 0); }

/* ── Site notice (the cookie banner that admits there are no cookies) ──── */

/* A bar on the bottom edge, not a card floating over the content. A panel
   parked in the corner of the hero covers the first thing anyone reads, and
   this notice is informational — it has not earned that space. */
.notice {
  position: fixed; left: 0; right: 0; bottom: 0;
  z-index: var(--z-float);
  background: var(--surface);
  border-top: 1px solid var(--line);
  padding: 16px var(--gut);
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 14px 28px;
  transform: translateY(100%); visibility: hidden;
  transition: transform 320ms var(--ease), visibility 320ms;
}
.notice[data-show="true"] { transform: none; visibility: visible; }
.notice .n-text { display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap; flex: 1 1 460px; }
.notice .eyebrow { flex: none; }
.notice p { font-size: var(--s-sm); margin: 0; max-width: 78ch; }
.notice .n-actions { display: flex; flex-wrap: wrap; gap: 10px; flex: none; }
/* The rail must not sit on top of the bar while it is up. :has() rather than a
   sibling combinator because the rail is markup-ordered BEFORE the notice. */
body:has(.notice[data-show="true"]) .rail { bottom: calc(clamp(14px, 2.4vw, 26px) + 76px); }
@media (max-width: 760px) {
  .notice { padding: 16px var(--gut) 18px; }
  .notice .n-actions { width: 100%; }
  body:has(.notice[data-show="true"]) .rail { bottom: calc(clamp(14px, 2.4vw, 26px) + 150px); }
}

/* ── Contact panel ─────────────────────────────────────────────────────── */

.contact-list { border-top: 1px solid var(--line); }
.contact-list .c-row {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 15px 0; border-bottom: 1px solid var(--line);
}
.contact-list .c-row .c-what { font-family: var(--mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--dim); }
.contact-list .c-row .c-val { font-size: var(--s-sm); color: var(--text); margin-top: 5px; }
.contact-list .c-row a.c-val { display: block; }
.contact-list .c-row a.c-val:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ── FAQ: animated open, plus expand/collapse all ──────────────────────── */

/* Height is animated with a grid-rows trick rather than max-height, so the
   panel never over- or under-shoots on long answers. */
.faq .a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 300ms var(--ease); }
.faq details[open] .a { grid-template-rows: 1fr; }
.faq .a > div { overflow: hidden; }
.faq .a p { padding-bottom: clamp(22px, 2.6vw, 32px); }
.faq details[data-hit="true"] { background: var(--wash-2); }
.faq-tools { display: flex; justify-content: flex-end; margin-bottom: 14px; }

/* ── Last updated ──────────────────────────────────────────────────────── */

.updated { font-family: var(--mono); font-size: 11px; letter-spacing: 0.05em; color: var(--dim); }

/* ── Print ─────────────────────────────────────────────────────────────── */

/* A monochrome dark site prints as a black rectangle unless you say otherwise.
   Print gets ink on paper, no chrome, and every link's destination spelled out. */
@media print {
  :root {
    --bg: #fff; --surface: #fff; --surface-2: #fff;
    --text: #000; --muted: #222; --dim: #555;
    --line: #bbb; --line-soft: #ddd; --line-hard: #888;
    --pure: #000; --invert-bg: #000; --invert-fg: #fff;
    --wash: transparent; --wash-2: transparent;
    --sec: 26px;
  }
  html { scroll-behavior: auto; }
  body { background: #fff; color: #000; font-size: 11pt; line-height: 1.45; }

  .site-head, .rail, .notice, .toast, .mobile-nav, .skip, .progress,
  .head-tools, .faq-tools, .anchor, .copy, dialog, .hero-mark, .hero-cta { display: none !important; }

  main, section, .wrap, .narrow { padding: 0 !important; margin: 0 !important; max-width: none !important; }
  section { padding: 0 0 18pt !important; break-inside: avoid; }
  [data-reveal] { opacity: 1 !important; transform: none !important; }

  h1 { font-size: 22pt; } h2 { font-size: 15pt; } h3 { font-size: 12pt; }
  h1, h2, h3 { break-after: avoid; }
  p, li { orphans: 3; widows: 3; }

  .faq .a { grid-template-rows: 1fr !important; }
  .faq details { break-inside: avoid; }

  /* Paper has no hover, so a bare "read the full policy" is a dead end. */
  a[href^="http"]::after,
  a[href^="mailto:"]::after { content: " (" attr(href) ")"; font-size: 8pt; color: #555; word-break: break-all; }
  a[href^="/"]::after { content: " (lockin.cz" attr(href) ")"; font-size: 8pt; color: #555; }

  .strip, .plans, .billing, .foot-grid { break-inside: avoid; }
  .site-foot { border-top: 1px solid #bbb; padding-top: 14pt; }
}

/* ── Reduced motion, for everything added above ────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .mobile-nav .m-links a { opacity: 1; transform: none; }
  .sk span { animation: none; }
  dialog[open], dialog[open]::backdrop { animation: none; }
  .faq .a { transition: none; }
}

/* ── Touch targets ─────────────────────────────────────────────────────────
   The chrome is sized for a cursor. On a coarse pointer every control has to
   clear 44px, so the boxes grow without the icons inside them changing size. */
@media (pointer: coarse), (max-width: 620px) {
  .ibtn { width: 44px; height: 44px; }
  .search-open { height: 44px; }
  @media (max-width: 1040px) { .search-open { width: 46px; } }
  .theme-seg { height: 44px; }
  .theme-seg button { width: 44px; }
  .anchor { padding: 14px; }
  .copy { padding: 14px 15px; }
  .btn-sm { min-height: 44px; }
  .theme-seg { height: 46px; }
  .theme-seg button { width: 46px; }
  .search-open { height: 46px; }
  .foot-col a { padding: 11px 0; }
  .contact-list .c-row { padding: 18px 0; }
  /* The wordmark is type, so it gets its hit area from padding, not a box. */
  .site-head .wordmark, .m-head .wordmark { padding: 12px 0; }
}
