/* ==========================================================================
   Tical design system
   Derived from the Tical.Backend landing page, rebuilt with semantic tokens,
   an elevation scale, and a real motion layer.
   ========================================================================== */

/* Every face this site uses is served from our own origin. That is a privacy decision
   before it is a performance one: a Google Fonts <link> hands the visitor's IP address
   to a third party on every page load, which the privacy policy would then have to
   disclose. Nothing here is fetched from anyone else.

   Both families are variable fonts, so one file covers the whole weight range and the
   `font-weight: A B` descriptor tells the browser so — four files, not sixteen. Only the
   latin and latin-ext subsets are shipped; latin-ext is not optional, because the legal
   pages carry Polish diacritics. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url('/fonts/jetbrains-mono-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url('/fonts/jetbrains-mono-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* The app's wordmark face, self-hosted from src/Tical/Assets. Used in exactly one
   place — the app mockup's title bar — so it loads lazily via font-display:swap. */
@font-face {
  font-family: 'Saira Stencil One';
  src: url('/fonts/SairaStencilOne-Regular.ttf') format('truetype');
  font-weight: 400;
  font-display: swap;
}

:root {
  color-scheme: dark;

  /* --- palette ------------------------------------------------------- */
  --lime-300: #bef264;
  --lime-400: #a3e635;
  --lime-500: #84cc16;
  --n-950: #0a0a0a;
  --n-900: #171717;
  --n-850: #1f1f1f;
  --n-800: #262626;
  --n-700: #404040;

  /* --- semantic ------------------------------------------------------- */
  --bg: var(--n-950);
  --surface: var(--n-900);
  --surface-2: var(--n-850);
  --border: var(--n-800);
  --border-strong: var(--n-700);
  --accent: var(--lime-400);
  --accent-hover: var(--lime-300);
  --accent-deep: var(--lime-500);
  --text: #f8fafc;
  --text-dim: #94a3b8;
  --text-faint: #64748b;
  --danger: #ff6b6b;
  --warn: #fbbf24;
  --ok: var(--lime-400);

  /* --- elevation ------------------------------------------------------ */
  /* The source design had none — depth came only from 1px borders. */
  --sh-1: 0 1px 2px rgb(0 0 0 / .4);
  --sh-2: 0 8px 24px -8px rgb(0 0 0 / .6);
  --sh-3: 0 24px 64px -16px rgb(0 0 0 / .8);
  --sh-glow: 0 0 0 1px rgb(163 230 53 / .25), 0 8px 32px -8px rgb(163 230 53 / .25);

  /* --- motion --------------------------------------------------------- */
  --e-out: cubic-bezier(.16, 1, .3, 1);        /* expo-out: the signature easing */
  --e-spring: cubic-bezier(.34, 1.56, .64, 1); /* overshoot for badges/toasts */
  --e-in-out: cubic-bezier(.65, 0, .35, 1);
  --t-fast: .18s;
  --t-base: .32s;
  --t-slow: .6s;

  /* --- shape / type --------------------------------------------------- */
  --r-sm: .5rem;
  --r-md: 1rem;
  --r-lg: 1.5rem;
  --r-pill: 999px;
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Code', Consolas, monospace;
  --header-h: 4.5rem;
}

/* ==========================================================================
   Reset & base
   ========================================================================== */

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

html {
  scroll-behavior: smooth;
  /* Anchor targets clear the sticky header instead of hiding under it. */
  scroll-padding-top: calc(var(--header-h) + 1rem);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background-color: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  font-family: var(--font-mono);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -.02em;
  margin: 0 0 1rem;
}

h1 { font-size: clamp(2.5rem, 7vw, 4.5rem); }
h2 { font-size: clamp(1.75rem, 4vw, 2.5rem); }
h3 { font-size: 1.25rem; }

p { margin: 0 0 1rem; }
a { color: var(--accent); text-decoration: none; }

code, kbd, samp, pre, .mono { font-family: var(--font-mono); }

::selection { background: rgb(163 230 53 / .3); color: var(--text); }

hr { border: 0; border-top: 1px solid var(--border); margin: 2rem 0; }

img, svg { vertical-align: middle; max-width: 100%; }

/* Every interactive element gets a visible keyboard ring. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}
:focus:not(:focus-visible) { outline: none; }

.container {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 1.5rem;
}
.container-narrow { max-width: 640px; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}

[hidden] { display: none !important; }

/* Skip link — the source design had none. */
.skip-link {
  position: absolute; top: -100%; left: 1rem; z-index: 2000;
  background: var(--accent); color: var(--n-950);
  padding: .75rem 1.25rem; border-radius: 0 0 var(--r-sm) var(--r-sm);
  font-weight: 700;
  transition: top var(--t-base) var(--e-out);
}
.skip-link:focus { top: 0; }

/* ==========================================================================
   Ambient background — aurora blobs + drifting grid
   ========================================================================== */

.bg-fx {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
}

/* Faint technical grid, masked to fade toward the edges. */
.bg-grid {
  position: absolute;
  inset: -50%;
  background-image:
    linear-gradient(to right, rgb(255 255 255 / .028) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(255 255 255 / .028) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(ellipse 70% 60% at 50% 30%, #000 20%, transparent 75%);
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 30%, #000 20%, transparent 75%);
  animation: grid-drift 60s linear infinite;
}

@keyframes grid-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(64px, 64px, 0); }
}

.aurora {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: .5;
  will-change: transform;
}
.aurora-1 {
  width: 46vw; height: 46vw; min-width: 320px; min-height: 320px;
  top: -12vw; left: -6vw;
  background: radial-gradient(circle, rgb(163 230 53 / .38), transparent 68%);
  animation: drift-a 20s var(--e-in-out) infinite alternate;
}
.aurora-2 {
  width: 40vw; height: 40vw; min-width: 280px; min-height: 280px;
  top: 8vw; right: -10vw;
  background: radial-gradient(circle, rgb(16 185 129 / .28), transparent 68%);
  animation: drift-b 28s var(--e-in-out) infinite alternate;
}
.aurora-3 {
  width: 34vw; height: 34vw; min-width: 240px; min-height: 240px;
  top: 62vh; left: 28vw;
  background: radial-gradient(circle, rgb(132 204 22 / .18), transparent 70%);
  animation: drift-a 34s var(--e-in-out) infinite alternate-reverse;
}

@keyframes drift-a {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(8vw, 6vh, 0) scale(1.18); }
}
@keyframes drift-b {
  from { transform: translate3d(0, 0, 0) scale(1.1); }
  to   { transform: translate3d(-7vw, 9vh, 0) scale(.9); }
}

/* ==========================================================================
   Header
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 1000;
  background-color: rgb(10 10 10 / .72);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  border-bottom: 1px solid var(--border);
  /* Explicit properties, not `transition: all` — the source transitioned
     everything, which forces needless repaints on a blurred sticky element. */
  transition: padding var(--t-base) var(--e-out),
              background-color var(--t-base) var(--e-out),
              box-shadow var(--t-base) var(--e-out);
  padding: 1.15rem 0;
}
.site-header.scrolled {
  padding: .6rem 0;
  background-color: rgb(10 10 10 / .92);
  box-shadow: var(--sh-2);
}

/* Reading-progress hairline pinned to the header's bottom edge. */
.scroll-progress {
  position: absolute;
  left: 0; bottom: -1px;
  height: 2px;
  width: 0;
  background: linear-gradient(90deg, var(--accent-deep), var(--accent), var(--accent-hover));
  box-shadow: 0 0 10px rgb(163 230 53 / .7);
  transition: width .1s linear;
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

.logo {
  display: inline-flex;
  align-items: center;
  gap: .7rem;
  font-family: var(--font-mono);
  font-size: 1.2rem;
  font-weight: 800;
  color: var(--accent);
  letter-spacing: -.03em;
  transition: transform var(--t-fast) var(--e-out);
}
.logo:hover { transform: translateX(2px); }
/* The brand mark itself — Tical's app icon. */
.logo-mark {
  width: 30px; height: 30px;
  flex: 0 0 auto;
  display: block;
  border-radius: 50%;
  box-shadow: 0 4px 14px -6px rgb(0 0 0 / .8);
  transition: transform var(--t-base) var(--e-spring);
}
.logo:hover .logo-mark { transform: scale(1.08); }

.site-nav ul {
  display: flex;
  align-items: center;
  gap: 2rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.site-nav a {
  position: relative;
  color: var(--text-dim);
  font-size: .9rem;
  font-weight: 500;
  padding: .25rem 0;
  transition: color var(--t-fast) var(--e-out);
}
/* Underline wipes out from the centre rather than just recolouring. */
.site-nav a::after {
  content: "";
  position: absolute;
  left: 50%; bottom: 0;
  width: 0; height: 1.5px;
  background: var(--accent);
  transform: translateX(-50%);
  transition: width var(--t-base) var(--e-out);
}
.site-nav a:hover { color: var(--text); }
.site-nav a:hover::after { width: 100%; }

/* Hamburger — bars morph into an X. */
.nav-toggle {
  display: none;
  width: 42px; height: 42px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  cursor: pointer;
  padding: 0;
  position: relative;
  transition: border-color var(--t-fast) var(--e-out);
}
.nav-toggle:hover { border-color: var(--border-strong); }
.nav-toggle span {
  position: absolute;
  left: 50%; top: 50%;
  width: 18px; height: 2px;
  margin-left: -9px;
  background: var(--text);
  border-radius: 2px;
  transition: transform var(--t-base) var(--e-out), opacity var(--t-fast) linear;
}
.nav-toggle span:nth-child(1) { transform: translateY(-6px); }
.nav-toggle span:nth-child(2) { transform: translateY(0); }
.nav-toggle span:nth-child(3) { transform: translateY(6px); }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; transform: scaleX(0); }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: rotate(-45deg); }

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: .8rem 1.75rem;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  font-family: var(--font-sans);
  font-size: .95rem;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  overflow: hidden;
  white-space: nowrap;
  transition: background-color var(--t-fast) var(--e-out),
              border-color var(--t-fast) var(--e-out),
              color var(--t-fast) var(--e-out),
              box-shadow var(--t-base) var(--e-out),
              transform var(--t-base) var(--e-out);
}

/* Shine sweep — a skewed highlight crossing the face on hover. */
.btn::after {
  content: "";
  position: absolute;
  top: -50%; left: -80%;
  width: 45%; height: 200%;
  background: linear-gradient(90deg, transparent, rgb(255 255 255 / .35), transparent);
  transform: skewX(-22deg);
  transition: left var(--t-slow) var(--e-out);
  pointer-events: none;
}
.btn:hover::after { left: 130%; }

.btn-primary {
  background-color: var(--accent);
  color: var(--n-950);
  box-shadow: 0 4px 16px -6px rgb(163 230 53 / .7);
}
.btn-primary:hover {
  background-color: var(--accent-hover);
  box-shadow: 0 10px 28px -8px rgb(163 230 53 / .8);
}

.btn-secondary {
  background-color: rgb(255 255 255 / .03);
  color: var(--text);
  border-color: var(--border);
}
.btn-secondary:hover {
  background-color: var(--surface-2);
  border-color: var(--border-strong);
}
.btn-secondary::after { background: linear-gradient(90deg, transparent, rgb(255 255 255 / .1), transparent); }

.btn-ghost {
  background: transparent;
  color: var(--text-dim);
  border-color: transparent;
  padding: .5rem .9rem;
}
.btn-ghost:hover { color: var(--text); background: rgb(255 255 255 / .05); }

.btn-danger { background-color: rgb(255 107 107 / .12); color: var(--danger); border-color: rgb(255 107 107 / .35); }
.btn-danger:hover { background-color: rgb(255 107 107 / .2); border-color: var(--danger); }

.btn-sm { padding: .5rem 1rem; font-size: .82rem; }
.btn-block { width: 100%; }

.btn:disabled, .btn[aria-disabled="true"] {
  opacity: .45;
  cursor: not-allowed;
  transform: none !important;
  box-shadow: none;
}
.btn:disabled::after { display: none; }

/* Spinner shown while a button is in its busy state. */
.btn.is-busy { color: transparent !important; pointer-events: none; }
.btn.is-busy::before {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 16px; height: 16px;
  margin: -8px 0 0 -8px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  color: var(--n-950);
  animation: spin .6s linear infinite;
}
.btn-secondary.is-busy::before, .btn-ghost.is-busy::before { color: var(--text); }

@keyframes spin { to { transform: rotate(360deg); } }

/* ==========================================================================
   Surfaces & cards
   ========================================================================== */

.card {
  position: relative;
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 2rem;
  overflow: hidden;
  transition: transform var(--t-base) var(--e-out),
              border-color var(--t-base) var(--e-out),
              box-shadow var(--t-base) var(--e-out);
}

/* Cursor-tracking spotlight. `--mx`/`--my` are written by motion.js. */
.card::before {
  content: "";
  position: absolute;
  inset: 0;
  /* The card's own `overflow: hidden` normally keeps this inside the rounded corners.
     Cards that opt out of clipping (.pricing-card) still need the gradient to follow
     the radius, so it clips itself. */
  border-radius: inherit;
  background: radial-gradient(400px circle at var(--mx, 50%) var(--my, 50%),
              rgb(163 230 53 / .09), transparent 65%);
  opacity: 0;
  transition: opacity var(--t-base) var(--e-out);
  pointer-events: none;
}
.card:hover::before { opacity: 1; }

.card-hover:hover {
  transform: translateY(-4px);
  border-color: var(--border-strong);
  box-shadow: var(--sh-2);
}

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

.panel {
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 1.5rem;
}

.inset {
  background-color: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 1rem;
}

/* ==========================================================================
   Scroll reveal
   ========================================================================== */

.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--t-slow) var(--e-out), transform var(--t-slow) var(--e-out);
  transition-delay: calc(var(--i, 0) * 70ms);
}
.reveal.in-view { opacity: 1; transform: none; }

.reveal-scale { transform: translateY(16px) scale(.97); }
.reveal-left  { transform: translateX(-28px); }
.reveal-right { transform: translateX(28px); }

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
  position: relative;
  padding: clamp(3.5rem, 10vh, 7rem) 0 clamp(3rem, 8vh, 5rem);
}

/* Copy on the left, the live clock on the right. Stacks and re-centres below 860px. */
.hero-grid {
  display: grid;
  grid-template-columns: 1.1fr .9fr;
  align-items: center;
  gap: clamp(2rem, 5vw, 4.5rem);
}
.hero-copy .hero-sub { margin-left: 0; margin-right: 0; }
.hero-copy .hero-actions { justify-content: flex-start; }

.hero-visual {
  display: grid;
  justify-items: center;
  gap: 1.5rem;
  opacity: 0;
  animation: fade-up 1s var(--e-out) .35s forwards;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  padding: .4rem 1rem;
  margin-bottom: 1.75rem;
  border: 1px solid rgb(163 230 53 / .3);
  border-radius: var(--r-pill);
  background: rgb(163 230 53 / .07);
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.eyebrow .dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse-dot 2s var(--e-in-out) infinite;
}
@keyframes pulse-dot {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgb(163 230 53 / .6); }
  50%      { opacity: .6; box-shadow: 0 0 0 6px rgb(163 230 53 / 0); }
}

/* Word-by-word headline entrance. Spans are emitted by the markup. */
.hero h1 .word {
  display: inline-block;
  opacity: 0;
  transform: translateY(1.1em) rotate(3deg);
  animation: word-rise .9s var(--e-out) forwards;
  animation-delay: calc(var(--i) * 80ms);
}
@keyframes word-rise {
  to { opacity: 1; transform: none; }
}

.hero .accent {
  background: linear-gradient(115deg, var(--accent-hover), var(--accent), var(--accent-deep));
  background-size: 200% auto;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: word-rise .9s var(--e-out) forwards, shimmer 6s linear infinite 1s;
  animation-delay: calc(var(--i) * 80ms), 1s;
}
@keyframes shimmer {
  to { background-position: 200% center; }
}

.hero-sub {
  max-width: 34rem;
  margin: 0 auto 2.5rem;
  font-size: clamp(1rem, 2.2vw, 1.2rem);
  color: var(--text-dim);
  opacity: 0;
  animation: fade-up .8s var(--e-out) .5s forwards;
}
.hero-actions {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1rem;
  opacity: 0;
  animation: fade-up .8s var(--e-out) .68s forwards;
}
.hero-note {
  margin-top: 1.25rem;
  font-size: .8rem;
  color: var(--text-faint);
  opacity: 0;
  animation: fade-up .8s var(--e-out) .85s forwards;
}

@keyframes fade-up {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}

/* ==========================================================================
   Sections & grids
   ========================================================================== */

.section { padding: clamp(3.5rem, 9vh, 6rem) 0; }
.section-head { text-align: center; max-width: 40rem; margin: 0 auto 3rem; }
.section-head p { color: var(--text-dim); margin: 0; }
.section-label {
  display: block;
  font-family: var(--font-mono);
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: .75rem;
}

.grid { display: grid; gap: 1.5rem; }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }

.feature-icon {
  width: 44px; height: 44px;
  display: grid; place-items: center;
  margin-bottom: 1.25rem;
  border-radius: 12px;
  background: rgb(163 230 53 / .1);
  border: 1px solid rgb(163 230 53 / .22);
  color: var(--accent);
  transition: transform var(--t-base) var(--e-spring),
              background-color var(--t-base) var(--e-out);
}
.card-hover:hover .feature-icon {
  transform: scale(1.1) rotate(-6deg);
  background: rgb(163 230 53 / .18);
}
.feature-card h3 { color: var(--text); margin-bottom: .5rem; font-size: 1.05rem; }
.feature-card p { color: var(--text-dim); font-size: .92rem; margin: 0; }

/* ==========================================================================
   Pricing
   ========================================================================== */

.pricing-grid {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1.5rem;
}
.pricing-card {
  flex: 1 1 300px;
  max-width: 360px;
  display: flex;
  flex-direction: column;
  padding: 2.5rem 2rem;
  /* The RECOMMENDED badge straddles the top border on purpose, so this surface must not
     clip the way every other .card does — `overflow: hidden` there cut it in half. */
  overflow: visible;
}
.pricing-card.featured {
  border-color: rgb(163 230 53 / .5);
  box-shadow: var(--sh-glow);
}
.pricing-card.featured::after {
  content: "RECOMMENDED";
  position: absolute;
  top: 0; left: 50%;
  transform: translate(-50%, -50%);
  background-color: var(--accent);
  color: var(--n-950);
  font-family: var(--font-mono);
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .1em;
  padding: .3rem .9rem;
  border-radius: var(--r-pill);
  z-index: 2;
  animation: badge-drop .7s var(--e-spring) .3s backwards;
}
@keyframes badge-drop {
  from { opacity: 0; transform: translate(-50%, -180%) scale(.8); }
}

.price {
  display: flex;
  align-items: baseline;
  gap: .4rem;
  font-family: var(--font-mono);
  font-size: 2.75rem;
  font-weight: 700;
  margin: 1.25rem 0 .25rem;
  letter-spacing: -.04em;
}
.price small { font-size: .9rem; font-weight: 400; color: var(--text-dim); }

.feature-list { list-style: none; padding: 0; margin: 1.75rem 0; flex: 1; }
.feature-list li {
  display: flex;
  align-items: flex-start;
  gap: .65rem;
  margin-bottom: .7rem;
  font-size: .92rem;
  color: var(--text-dim);
}
.feature-list li::before {
  content: "";
  flex: 0 0 auto;
  width: 18px; height: 18px;
  margin-top: .18rem;
  border-radius: 50%;
  background: rgb(163 230 53 / .14) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a3e635' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center / 11px no-repeat;
}
.feature-list li.muted::before {
  background: rgb(148 163 184 / .12) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='3.5' stroke-linecap='round'%3E%3Cline x1='6' y1='12' x2='18' y2='12'/%3E%3C/svg%3E") center / 11px no-repeat;
}

/* ==========================================================================
   Forms
   ========================================================================== */

.field { margin-bottom: 1.25rem; }
.label {
  display: block;
  margin-bottom: .5rem;
  font-size: .82rem;
  font-weight: 600;
  color: var(--text-dim);
  letter-spacing: .02em;
}
.hint { font-size: .78rem; color: var(--text-faint); margin: .4rem 0 0; }

.input, .textarea, .select {
  width: 100%;
  background-color: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: .75rem .9rem;
  font-family: var(--font-sans);
  font-size: .92rem;
  line-height: 1.5;
  transition: border-color var(--t-fast) var(--e-out),
              box-shadow var(--t-base) var(--e-out),
              background-color var(--t-fast) var(--e-out);
}
.input:hover, .textarea:hover, .select:hover { border-color: var(--border-strong); }
.input:focus, .textarea:focus, .select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgb(163 230 53 / .15);
  background-color: var(--surface);
}
.textarea {
  min-height: 100px;
  resize: vertical;
  font-family: var(--font-mono);
  font-size: .82rem;
  letter-spacing: .01em;
}
.input.mono { font-family: var(--font-mono); font-size: .85rem; }
.input::placeholder, .textarea::placeholder { color: var(--text-faint); }

.input.invalid, .textarea.invalid {
  border-color: var(--danger);
  animation: shake .4s var(--e-in-out);
}
@keyframes shake {
  10%, 90% { transform: translateX(-2px); }
  20%, 80% { transform: translateX(4px); }
  30%, 50%, 70% { transform: translateX(-6px); }
  40%, 60% { transform: translateX(6px); }
}

.form-error {
  display: flex;
  align-items: center;
  gap: .5rem;
  color: var(--danger);
  font-size: .85rem;
  margin-top: .6rem;
  animation: fade-up .3s var(--e-out);
}

/* ==========================================================================
   Code / key display
   ========================================================================== */

.keybox {
  position: relative;
  background-color: var(--bg);
  border: 1px dashed rgb(163 230 53 / .45);
  border-radius: var(--r-sm);
  padding: 1rem;
  font-family: var(--font-mono);
  font-size: .78rem;
  line-height: 1.7;
  word-break: break-all;
  color: var(--accent-hover);
  overflow: hidden;
}
/* One-shot shimmer when the key first appears. */
.keybox.fresh::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 30%, rgb(163 230 53 / .18) 50%, transparent 70%);
  transform: translateX(-100%);
  animation: sweep 1.4s var(--e-out) .2s;
}
@keyframes sweep { to { transform: translateX(100%); } }

/* ==========================================================================
   Badges & pills
   ========================================================================== */

.badge {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .2rem .6rem;
  border-radius: var(--r-pill);
  font-family: var(--font-mono);
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .04em;
  border: 1px solid transparent;
  white-space: nowrap;
}
.badge-ok      { background: rgb(163 230 53 / .12); color: var(--accent); border-color: rgb(163 230 53 / .3); }
.badge-danger  { background: rgb(255 107 107 / .12); color: var(--danger); border-color: rgb(255 107 107 / .3); }
.badge-warn    { background: rgb(251 191 36 / .12); color: var(--warn); border-color: rgb(251 191 36 / .3); }
.badge-muted   { background: rgb(148 163 184 / .1); color: var(--text-dim); border-color: rgb(148 163 184 / .22); }

/* ==========================================================================
   Success moment — self-drawing checkmark
   ========================================================================== */

.success-mark {
  width: 60px; height: 60px;
  margin: 0 auto 1.25rem;
  display: block;
}
.success-mark circle {
  stroke: var(--accent);
  stroke-width: 2;
  fill: rgb(163 230 53 / .08);
  stroke-dasharray: 166;
  stroke-dashoffset: 166;
  animation: draw .7s var(--e-out) forwards;
}
.success-mark path {
  stroke: var(--accent);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
  stroke-dasharray: 48;
  stroke-dashoffset: 48;
  animation: draw .45s var(--e-out) .55s forwards;
}
@keyframes draw { to { stroke-dashoffset: 0; } }

.pulse-border { animation: pulse-border 1.6s var(--e-out) .2s; }
@keyframes pulse-border {
  0%   { box-shadow: 0 0 0 0 rgb(163 230 53 / .5); }
  100% { box-shadow: 0 0 0 22px rgb(163 230 53 / 0); }
}

/* ==========================================================================
   Loading — indeterminate bar & skeletons
   ========================================================================== */

.progress-indeterminate {
  position: relative;
  height: 3px;
  width: 100%;
  border-radius: var(--r-pill);
  background: var(--border);
  overflow: hidden;
}
.progress-indeterminate::after {
  content: "";
  position: absolute;
  inset: 0;
  width: 40%;
  border-radius: inherit;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  animation: indeterminate 1.4s var(--e-in-out) infinite;
}
@keyframes indeterminate {
  from { transform: translateX(-100%); }
  to   { transform: translateX(350%); }
}

.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--surface-2);
  border-radius: var(--r-sm);
  height: 1rem;
}
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgb(255 255 255 / .06), transparent);
  transform: translateX(-100%);
  animation: skeleton-sweep 1.5s ease-in-out infinite;
}
@keyframes skeleton-sweep { to { transform: translateX(100%); } }

.dots::after {
  content: "";
  animation: dots 1.4s steps(4, end) infinite;
}
@keyframes dots {
  0%   { content: ""; }
  25%  { content: "."; }
  50%  { content: ".."; }
  75%  { content: "..."; }
}

/* ==========================================================================
   Stepped state machine (redeem portal)
   ========================================================================== */

/* The wrapper animates its height so the card grows rather than jumping. */
.stage {
  position: relative;
  transition: height var(--t-slow) var(--e-out);
  overflow: hidden;
}
.step {
  transition: opacity var(--t-base) var(--e-out), transform var(--t-base) var(--e-out);
}
/* Steps toggle via `.is-hidden`, never the `hidden` attribute — the element must
   stay measurable (scrollHeight) while it fades so the stage can size to it. */
.step.leaving { opacity: 0; transform: translateY(-10px); pointer-events: none; }
.step.entering { opacity: 0; transform: translateY(14px); }
.step.is-hidden { display: none !important; }

/* ==========================================================================
   Toasts
   ========================================================================== */

.toast-stack {
  position: fixed;
  right: 1.25rem; bottom: 1.25rem;
  z-index: 3000;
  display: flex;
  flex-direction: column-reverse;
  gap: .6rem;
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: center;
  gap: .65rem;
  min-width: 240px;
  max-width: min(90vw, 380px);
  padding: .8rem 1rem;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-sm);
  box-shadow: var(--sh-3);
  font-size: .88rem;
  pointer-events: auto;
  animation: toast-in .45s var(--e-spring);
}
.toast.leaving { animation: toast-out .3s var(--e-out) forwards; }
.toast-danger { border-left-color: var(--danger); }
.toast-warn { border-left-color: var(--warn); }

@keyframes toast-in {
  from { opacity: 0; transform: translateX(120%) scale(.9); }
  to   { opacity: 1; transform: none; }
}
@keyframes toast-out {
  to { opacity: 0; transform: translateX(30%) scale(.95); }
}

/* ==========================================================================
   Modal
   ========================================================================== */

.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 2500;
  display: grid;
  place-items: center;
  padding: 1.5rem;
  background: rgb(0 0 0 / .7);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  opacity: 0;
  transition: opacity var(--t-base) var(--e-out);
}
.modal-backdrop.open { opacity: 1; }
.modal-backdrop[hidden] { display: none; }

.modal {
  width: 100%;
  max-width: 480px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  padding: 2rem;
  box-shadow: var(--sh-3);
  transform: scale(.96) translateY(12px);
  opacity: 0;
  transition: transform var(--t-base) var(--e-out), opacity var(--t-base) var(--e-out);
}
.modal-backdrop.open .modal { transform: none; opacity: 1; }
.modal h3 { margin-bottom: .5rem; }
.modal p { color: var(--text-dim); font-size: .9rem; }
.modal-actions { display: flex; gap: .75rem; justify-content: flex-end; margin-top: 1.75rem; }

/* ==========================================================================
   Stats
   ========================================================================== */

.stat-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.stat {
  padding: 1.25rem 1.4rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  transition: transform var(--t-base) var(--e-out), border-color var(--t-base) var(--e-out);
}
.stat:hover { transform: translateY(-3px); border-color: var(--border-strong); }
.stat-label {
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.stat-value {
  font-family: var(--font-mono);
  font-size: 2rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.03em;
  margin-top: .35rem;
  font-variant-numeric: tabular-nums;
}
.stat-value.accent { color: var(--accent); }
.stat-value.danger { color: var(--danger); }
.stat-value.warn { color: var(--warn); }

/* ==========================================================================
   Tables
   ========================================================================== */

.table-wrap {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow-x: auto;
  background: var(--surface);
}
table { width: 100%; border-collapse: collapse; font-size: .86rem; }
thead th {
  position: sticky;
  top: 0;
  background: var(--surface-2);
  text-align: left;
  padding: .8rem 1rem;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-faint);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
tbody td {
  padding: .8rem 1rem;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
tbody tr {
  transition: background-color var(--t-fast) var(--e-out);
  animation: row-in .4s var(--e-out) backwards;
  animation-delay: calc(var(--i, 0) * 35ms);
}
tbody tr:hover { background: rgb(255 255 255 / .025); }
tbody tr:last-child td { border-bottom: 0; }
@keyframes row-in {
  from { opacity: 0; transform: translateY(8px); }
}
td.mono, th.mono { font-family: var(--font-mono); font-size: .8rem; }
.td-actions { text-align: right; white-space: nowrap; }

.empty-state {
  padding: 3rem 1.5rem;
  text-align: center;
  color: var(--text-faint);
  font-size: .9rem;
}

/* ==========================================================================
   Tabs
   ========================================================================== */

.tabs {
  position: relative;
  display: flex;
  gap: .25rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 1.5rem;
}
.tab {
  position: relative;
  background: none;
  border: 0;
  padding: .75rem 1.1rem;
  color: var(--text-dim);
  font-family: var(--font-sans);
  font-size: .9rem;
  font-weight: 500;
  cursor: pointer;
  transition: color var(--t-fast) var(--e-out);
}
.tab:hover { color: var(--text); }
.tab[aria-selected="true"] { color: var(--accent); }
/* Sliding indicator; motion.js writes --tab-x / --tab-w. */
.tab-indicator {
  position: absolute;
  bottom: -1px;
  left: 0;
  height: 2px;
  width: var(--tab-w, 0);
  transform: translateX(var(--tab-x, 0));
  background: var(--accent);
  border-radius: 2px;
  transition: transform var(--t-base) var(--e-out), width var(--t-base) var(--e-out);
}

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
  padding: 3rem 0;
  margin-top: 4rem;
  border-top: 1px solid var(--border);
  color: var(--text-faint);
  font-size: .85rem;
}
.footer-inner {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
  justify-content: space-between;
}
.site-footer a { color: var(--text-dim); transition: color var(--t-fast) var(--e-out); }
.site-footer a:hover { color: var(--accent); }

/* ==========================================================================
   Status pages (404 / 429 / error)
   ========================================================================== */

.status-page {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 2rem 1.5rem;
  text-align: center;
}
.status-code {
  font-family: var(--font-mono);
  font-size: clamp(5rem, 22vw, 11rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.06em;
  background: linear-gradient(180deg, var(--text) 10%, rgb(163 230 53 / .35) 90%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: fade-up .8s var(--e-out) backwards;
}
.status-code.glitch { position: relative; animation: fade-up .8s var(--e-out) backwards, glitch 5s steps(1) infinite 1.5s; }
@keyframes glitch {
  0%, 96%, 100% { transform: none; opacity: 1; }
  97% { transform: translate(-3px, 1px) skewX(4deg); opacity: .85; }
  98% { transform: translate(3px, -1px) skewX(-3deg); }
  99% { transform: none; }
}

/* ==========================================================================
   Utilities
   ========================================================================== */

.stack > * + * { margin-top: var(--gap, 1rem); }
.row { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.text-dim { color: var(--text-dim); }
.text-faint { color: var(--text-faint); }
.text-accent { color: var(--accent); }
.text-danger { color: var(--danger); }
.text-center { text-align: center; }
.text-sm { font-size: .85rem; }
.text-xs { font-size: .78rem; }
.mt-0 { margin-top: 0; } .mt-1 { margin-top: .5rem; } .mt-2 { margin-top: 1rem; }
.mt-3 { margin-top: 1.5rem; } .mt-4 { margin-top: 2rem; }
.mb-0 { margin-bottom: 0; } .mb-2 { margin-bottom: 1rem; } .mb-3 { margin-bottom: 1.5rem; }
.flex-1 { flex: 1; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }

.callout {
  display: flex;
  gap: .75rem;
  padding: .9rem 1rem;
  border-radius: var(--r-sm);
  font-size: .85rem;
  line-height: 1.55;
  border: 1px solid;
}
.callout-warn { background: rgb(251 191 36 / .07); border-color: rgb(251 191 36 / .3); color: #fde68a; }
.callout-info { background: rgb(163 230 53 / .06); border-color: rgb(163 230 53 / .25); color: var(--text-dim); }

/* ==========================================================================
   Clocks & time
   ========================================================================== */

/* --- the hero clock: real time, real ticking --- */
.clock {
  position: relative;
  width: min(220px, 46vw);
  aspect-ratio: 1;
  margin: 0 auto;
  filter: drop-shadow(0 12px 32px rgb(163 230 53 / .18));
}
.clock svg { width: 100%; height: 100%; overflow: visible; }

.clock-face {
  fill: rgb(23 23 23 / .7);
  stroke: var(--border-strong);
  stroke-width: 1.5;
}
/* Elapsed-minutes arc, swept by JS via stroke-dashoffset. */
.clock-arc {
  fill: none;
  stroke: var(--accent);
  stroke-width: 3;
  stroke-linecap: round;
  opacity: .85;
  transform: rotate(-90deg);
  transform-origin: 100px 100px;
  transition: stroke-dashoffset 1s linear;
}
.clock-tick { stroke: var(--text-faint); stroke-width: 2; stroke-linecap: round; }
.clock-tick.major { stroke: var(--text-dim); stroke-width: 3; }

.clock .hand {
  stroke-linecap: round;
  transform-origin: 100px 100px;
}
.clock .hand-hour { stroke: var(--text); stroke-width: 6; }
.clock .hand-min  { stroke: var(--text); stroke-width: 4; }
/* The second hand steps, then settles with a touch of overshoot — like a real one. */
.clock .hand-sec  {
  stroke: var(--accent);
  stroke-width: 2;
  transition: transform .14s var(--e-spring);
}
.clock-pin { fill: var(--accent); }
.clock-pin-inner { fill: var(--n-950); }

/* Ring that pulses outward once per second. */
.clock-pulse {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid var(--accent);
  opacity: 0;
  pointer-events: none;
}
.clock-pulse.beat { animation: clock-beat 1s var(--e-out); }
@keyframes clock-beat {
  0%   { opacity: .5; transform: scale(.94); }
  100% { opacity: 0;  transform: scale(1.12); }
}

/* --- running session readout --- */
.live-timer {
  display: inline-flex;
  /* Two boxes only: the dot and the text group, both centred on the pill's middle. */
  align-items: center;
  gap: .6rem;
  padding: .5rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: rgb(23 23 23 / .6);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-family: var(--font-mono);
  font-size: .95rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: .04em;
}
/* The label and the readout are different faces at different sizes, so centring their
   boxes against each other leaves "Tracking" ~5px above the digits: equal line boxes are
   not equal baselines, since each font puts its baseline at a different height inside the
   em box. Align them on the real baseline here, and let the parent centre the group — with
   line-height 1 this box is exactly the readout's line box, whose ink is already centred
   in it, so the text lands on the dot's centre line. */
/* Deliberately NOT a flex container. The label and the readout are different faces at
   different sizes, and plain inline layout is what puts two such runs on a shared
   baseline — flex `align-items: baseline` adds slack below the line and leaves the text
   riding high. As a flex item of the pill this blockifies to a single line box whose
   height is the readout's, so centring it lands the text on the dot's centre line. */
.live-timer-text { line-height: 1; }
.live-timer .rec {
  flex: 0 0 auto;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--danger);
  animation: rec-blink 2s var(--e-in-out) infinite;
}
/* Collapse the inherited body line-height (1.65) so the pill hugs the text, now that
   the two runs are aligned on their baseline rather than by box. */
.live-timer .label,
.live-timer [data-live-timer] { line-height: 1; }
.live-timer .label {
  /* `.label` is the form-label rule (display:block; margin-bottom:.5rem) — inside the
     pill it has to be an ordinary inline run so it shares the readout's line box. */
  display: inline;
  margin-bottom: 0;
  /* The pill's `gap` spaces the dot from the text; inside the text this does it. */
  margin-right: .6rem;
  font-family: var(--font-sans);
  font-size: .75rem;
  font-weight: 500;
  color: var(--text-faint);
  letter-spacing: 0;
  /* Baseline-aligned by the rules above, which is correct — but the two faces have
     different cap heights, so a shared baseline still leaves this run's ink sitting about
     a pixel low against the digits. Optical nudge only; the line box does not move. */
  vertical-align: .08em;
}
@keyframes rec-blink {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgb(255 107 107 / .5); }
  50%      { opacity: .45; box-shadow: 0 0 0 5px rgb(255 107 107 / 0); }
}

/* ==========================================================================
   App mockup — the real Tical window, in the app's own tokens

   These are deliberately a separate, locally-scoped scale rather than the site's
   semantic vars: this block is a picture of the product, so it has to match the
   desktop app's palette exactly (src/Tical/App.axaml) and must not drift when the
   site's theme changes.
   ========================================================================== */

.app-mock {
  --a-bg: #0A0C10;
  --a-bg-soft: #0F1318;
  --a-sunken: #0D1016;
  --a-surface: #141820;
  --a-hover: #1E2433;
  --a-active: #2A3245;
  --a-border: #1E2433;
  --a-t1: #F0F4F8;
  --a-t2: #7B8794;
  --a-t3: #525E6B;
  --a-accent: #9BE64D;
  --a-danger: #FF6B6B;
  --a-warn: #FFB84D;

  /* The desktop app sets JetBrains Mono at Window level, so everything inherits it. */
  font-family: var(--font-mono);
  /* The window itself is 600x700 (MainWindow.axaml), so the picture is drawn at 1:1. */
  max-width: 37.5rem;
  margin: 0 auto;
  border: 1px solid var(--a-hover);
  border-radius: 12px;
  overflow: hidden;
  background: linear-gradient(180deg, var(--a-bg) 0%, var(--a-bg-soft) 50%, var(--a-bg) 100%);
  box-shadow: var(--sh-3), 0 0 0 1px rgb(0 0 0 / .5);
  position: relative;
  isolation: isolate;
}
/* AuroraGlow: the app paints a 260px-tall lime radial behind the shell, anchored to the
   top of the window. It is the only light source in the picture. */
.app-mock::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 260px;
  z-index: -1;
  background: radial-gradient(90% 90% at 50% 0%, rgb(155 230 77 / .102), transparent 70%);
  pointer-events: none;
}

/* Every glyph in here is the app's own PathIcon geometry on a 24x24 viewBox, so they
   are filled paths rather than the stroked icon set the rest of the site uses. */
.app-mock svg { fill: currentColor; flex: 0 0 auto; }

/* --- title bar (MainWindow.axaml: 40px, icon at 16, buttons 36x36 spaced 2) --- */
.am-titlebar {
  display: flex;
  align-items: center;
  gap: 2px;
  height: 40px;
  padding: 0 4px 0 16px;
  background: var(--a-bg);
}
.am-titlebar .am-icon { width: 20px; height: 20px; flex: 0 0 auto; }
.am-wordmark {
  font-family: 'Saira Stencil One', var(--font-mono);
  font-size: 1rem;
  color: var(--a-accent);
  opacity: .9;
  letter-spacing: .02em;
  /* margin-right:auto is the draggable spacer the app puts between the wordmark and
     its window buttons. Long-hand on purpose: the 3-value shorthand sets `bottom`. */
  margin-left: 6px;
  margin-right: auto;
}
.am-pill {
  font-size: .5625rem;      /* 9px */
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 10px;
  background: var(--a-accent);
  color: var(--a-bg);
  letter-spacing: .06em;
  margin-right: 8px;
}
/* Button.icon: chromeless until hover — no border at rest, which is what the title bar
   actually draws. Only the hover wash and the glyph colour change. */
.am-btn {
  width: 36px; height: 36px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  border: 0;
  color: var(--a-t2);
  background: none;
  transition: background var(--t-fast) var(--e-out), color var(--t-fast) var(--e-out);
}
.am-btn:hover { background: var(--a-hover); color: var(--a-t1); }
/* The close button is plain too; it washes to the muted danger surface on hover. */
.am-btn.danger:hover { background: #3D1A1A; color: var(--a-danger); }

/* --- tracker panel (MainView.axaml: StackPanel Margin 16,8,16,16 / Spacing 10) --- */
.am-top {
  display: grid;
  gap: 10px;
  padding: 8px 16px 16px;
}

/* --- context row -----------------------------------------------------------
   MainView.axaml lays this out as Grid ColumnDefinitions="Auto,*": the switcher
   pill, then the active context's MainBar slot 8px to its right. Both sit at
   ContextRowControlHeight (40px); Pomodoro's taller panel stretches the row. */
.am-ctxrow {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 8px;
  align-items: stretch;
}

.am-ctxswitch { position: relative; }

/* ToggleButton.contextTrigger */
.am-ctx-trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-height: 40px;
  padding: 7px 10px;
  border-radius: 8px;
  border: 1px solid var(--a-border);
  background: var(--a-surface);
  color: var(--a-t1);
  font-family: inherit;
  font-size: .75rem;          /* 12px */
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--t-base) var(--e-out), border-color var(--t-base) var(--e-out);
}
.am-ctx-trigger:hover { background: var(--a-hover); border-color: var(--a-active); }
.am-ctx-trigger > svg:first-child { width: 13px; height: 13px; color: var(--a-accent); }
.am-ctx-caret {
  width: 11px; height: 11px;
  color: var(--a-t2);
  transition: transform var(--t-base) var(--e-out);
}
/* :checked in the app — the pill borders itself in the accent while its popup is up. */
.am-ctx-trigger[aria-expanded="true"] {
  background: var(--a-hover);
  border-color: var(--a-accent);
}
.am-ctx-trigger[aria-expanded="true"] .am-ctx-caret { transform: rotate(180deg); }

/* Border.contextDropdownCard — a Popup, so it floats over the composer rather than
   pushing it down. */
.am-ctx-menu {
  position: absolute;
  z-index: 5;
  top: 100%;
  left: 0;
  margin-top: 8px;
  min-width: 220px;
  padding: 4px;
  border-radius: 10px;
  border: 1px solid var(--a-border);
  background: var(--a-surface);
  box-shadow: 0 12px 32px -6px rgb(0 0 0 / .7);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px) scale(.985);
  transform-origin: top left;
  /* visibility is switched, not interpolated: held until the fade-out finishes on close,
     flipped immediately on open. Transitioning it directly leaves the card unclickable
     if the transition is ever interrupted. */
  transition: opacity var(--t-base) var(--e-out), transform var(--t-base) var(--e-out),
              visibility 0s linear var(--t-base);
}
.am-ctx-menu.open {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}

/* Button.contextRow — Grid ColumnDefinitions="3,Auto,*,Auto,Auto" */
.am-ctx-item {
  display: grid;
  grid-template-columns: 3px auto minmax(0, 1fr) auto;
  align-items: center;
  width: 100%;
  margin: 1px 0;
  padding: 9px 8px;
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--a-t1);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--t-fast) var(--e-out);
}
.am-ctx-item:hover  { background: var(--a-hover); }
.am-ctx-item:active { background: var(--a-active); }
.am-ctx-item > svg {
  width: 13px; height: 13px;
  margin-left: 10px;
  color: var(--a-accent);
}
.am-ctx-itemname {
  margin: 0 8px 0 9px;
  font-size: .75rem;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* The 3px accent rail and the check both belong to the active row only. */
.am-ctx-rail {
  align-self: stretch;
  margin: 1px 0;
  border-radius: 2px;
  background: transparent;
}
.am-ctx-item.on .am-ctx-rail { background: var(--a-accent); }
.am-ctx-check { font-size: .75rem; color: var(--a-accent); opacity: 0; }
.am-ctx-item.on .am-ctx-check { opacity: 1; }

/* --- MainBar slot ---------------------------------------------------------- */
.am-mainbar {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

/* ComboBox / TextBox: sunken fill, 8px radius, at the shared row height. */
.am-picker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  min-height: 40px;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--a-border);
  background: var(--a-sunken);
  color: var(--a-t1);
  font-size: .8125rem;        /* 13px */
}
.am-picker.grow { flex: 1 1 0; }
.am-picker > span {
  min-width: 0;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.am-picker.empty > span { color: var(--a-t2); }
.am-picker svg { width: 12px; height: 12px; color: var(--a-t2); }

/* Button.icon — chromeless until hover, like the title bar's. */
.am-iconbtn {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 28px; height: 28px;
  border-radius: 6px;
  color: var(--a-t2);
  transition: background var(--t-fast) var(--e-out), color var(--t-fast) var(--e-out);
}
.am-iconbtn:hover { background: var(--a-hover); color: var(--a-t1); }
.am-iconbtn svg { width: 14px; height: 14px; }

.am-status { font-size: .6875rem; color: var(--a-t3); }
.am-status.ok   { color: var(--a-accent); }
.am-status.warn { color: var(--a-warn); }

/* Pomodoro's MainBar is a panel rather than a picker row, so it gets the card
   treatment and sets the row's height. */
.am-pomo {
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px solid var(--a-border);
  background: var(--a-surface);
}
.am-pomo-phase {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  font-size: .8125rem;
  font-weight: 600;
  color: var(--a-t1);
}
.am-pomo-phase i {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--a-t2);
}
.am-pomo-cycles { font-size: .6875rem; letter-spacing: 2px; color: var(--a-accent); }
.am-pomo .am-status { margin-left: auto; }

/* --- composer (Border.card.composer) ---------------------------------------
   One surface holding the description, the ProjectInput slot and the timer row —
   not four floating controls. CornerRadius 14, Padding 14,12, ShadowMd. */
.am-composer {
  position: relative;
  display: grid;
  gap: 10px;
  padding: 12px 14px;
  border-radius: 14px;
  border: 1px solid rgb(255 255 255 / .06);
  background: var(--a-surface);
  box-shadow: 0 2px 8px -1px rgb(0 0 0 / .35);
}
/* GlassEdgeBrush: a hairline brightest along the top edge, gone by a third of the way
   down. Drawn as an inset overlay because a border can't carry a gradient on its own. */
.am-composer::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(180deg, rgb(255 255 255 / .2) 0%, rgb(255 255 255 / .05) 35%, transparent 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite: exclude;
  pointer-events: none;
}
/* The description box has no surface of its own inside the card. */
.am-input {
  min-width: 0;
  font-size: .9375rem;        /* 15px */
  color: var(--a-t1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.am-input.empty { color: var(--a-t2); }   /* the "What are you working on?" watermark */

/* --- ProjectInput slot + tag editor ---------------------------------------- */
.am-projrow { display: grid; gap: 10px; }
.am-hair { height: 1px; background: var(--a-border); }
.am-field {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--a-sunken);
  color: var(--a-t1);
  font-size: .8125rem;
}
.am-field > svg { width: 12px; height: 12px; margin-left: auto; color: var(--a-t2); }
.am-field.empty { color: var(--a-t2); }
.am-tagbox { font-size: .75rem; padding: 6px 10px; }
.am-tagrow { display: grid; gap: 6px; }

/* --- timer row (Grid ColumnDefinitions="*,Auto,Auto") ----------------------- */
.am-timerrow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  margin-top: 2px;
}
.am-readout {
  font-size: 1.75rem;         /* 28px */
  font-weight: 700;
  color: var(--a-t1);
  font-variant-numeric: tabular-nums;
  /* DropShadowEffect BlurRadius=16 Color=AppAccent Opacity=0.55 */
  text-shadow: 0 0 16px rgb(155 230 77 / .55);
}

/* Start/stop: a 56px panel holding the ring layers over a 44px round button. */
.am-play {
  position: relative;
  width: 56px; height: 56px;
  margin: 0 16px;
  display: grid;
  place-items: center;
}
.am-ring { position: absolute; inset: 0; width: 56px; height: 56px; }
/* The ring is the one stroked drawing in here, so it has to out-specify the blanket
   `.app-mock svg { fill: currentColor }` that the filled PathIcon glyphs rely on. */
.app-mock .am-ring circle { fill: none; }
/* The static track the app always draws. */
.am-ring-track { stroke: var(--a-active); stroke-width: 2; }
/* The running arc: 6 degrees per second from twelve o'clock, so exactly one revolution
   per minute. 150.8 is the circumference at r=24. */
.am-ring-arc {
  stroke: var(--a-accent);
  stroke-width: 2.5;
  stroke-linecap: round;
  transform: rotate(-90deg);
  transform-origin: center;
  filter: drop-shadow(0 0 6px rgb(155 230 77 / .5));
  animation: am-sweep 60s linear infinite;
}
@keyframes am-sweep {
  from { stroke-dasharray: 0 150.8; }
  to   { stroke-dasharray: 150.8 150.8; }
}
.am-playface {
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  border-radius: 50%;
  color: var(--a-danger);       /* TimerColorConverter: red stop glyph while running */
  transition: background var(--t-fast) var(--e-out);
}
.am-play:hover .am-playface { background: #3D1A1A; }
.am-glyph { width: 16px; height: 16px; }

/* Button.minor, forced round: the manual-add button beside the timer. */
.am-add {
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid var(--a-border);
  color: var(--a-accent);
  transition: background var(--t-fast) var(--e-out), border-color var(--t-fast) var(--e-out);
}
.am-add:hover { background: var(--a-hover); border-color: var(--a-t2); }
.am-add svg { width: 22px; height: 22px; }

/* --- divider + search bar --------------------------------------------------- */
.am-divider { height: 1px; background: var(--a-border); margin: 0 1rem; }

.am-search {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 12px 16px 8px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--a-border);
  background: var(--a-surface);
  box-shadow: 0 1px 2px rgb(0 0 0 / .25);
  color: var(--a-t2);
  font-size: .8125rem;
}
.am-search svg { width: 14px; height: 14px; color: var(--a-t3); }

/* --- entry list (ListBox Margin 16,4,16,16) --------------------------------- */
.am-list { padding: 4px 16px 16px; }

/* Grid ColumnDefinitions="Auto,*,Auto": date, a hairline rule, then the day total. */
.am-dayhdr {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;      /* not baseline: the odometer total is an inline-flex box */
  margin: 14px 4px 8px;
  font-size: .6875rem;        /* 11px */
}
.am-dayhdr .am-date { color: var(--a-t2); font-weight: 600; letter-spacing: .04em; }
.am-dayhdr .am-rule { height: 1px; margin: 0 10px; background: var(--a-border); }
.am-dayhdr .am-total { color: var(--a-accent); font-weight: 700; font-variant-numeric: tabular-nums; }

.am-row {
  display: grid;
  grid-template-columns: 3px minmax(0, 1fr) auto 90px auto;
  align-items: center;
  background: var(--a-surface);
  border: 1px solid var(--a-border);
  border-radius: 10px;
  padding: 12px 14px;
  margin-bottom: 6px;
  transition: border-color var(--t-fast) var(--e-out);
}
.am-row:hover { border-color: var(--a-active); }

/* The accent rail: half-height at rest, growing to fill the row on hover. */
.am-rail {
  align-self: stretch;
  margin: 1px 0;
  border-radius: 2px;
  background: var(--a-accent);
  transform: scaleY(.5);
  transition: transform var(--t-base) var(--e-out);
}
.am-row:hover .am-rail { transform: scaleY(1); }

.am-body { min-width: 0; margin: 0 10px; display: grid; gap: 2px; }
.am-desc { font-size: .8125rem; font-weight: 500; color: var(--a-t1); }
.am-proj { font-size: .6875rem; color: var(--a-t3); }
.am-badge { font-size: .75rem; color: var(--a-t2); margin-right: 8px; }
.am-dur {
  text-align: right;
  margin-right: 10px;
  font-size: .875rem;         /* 14px */
  font-weight: 700;
  color: var(--a-t1);
  font-variant-numeric: tabular-nums;
}
.am-kebab {
  display: grid;
  place-items: center;
  padding: 6px;
  border-radius: 6px;
  color: var(--a-t2);
  transition: background var(--t-fast) var(--e-out), color var(--t-fast) var(--e-out);
}
.am-kebab svg { width: 14px; height: 14px; }
.am-row:hover .am-kebab { background: var(--a-hover); color: var(--a-t1); }

/* ProgressBar.durationBar: this entry's share of its day, filled in AppAccentDimBrush.
   The width comes from initAppMock, which measures each row against its day's longest. */
.am-bar {
  grid-column: 1 / -1;
  margin: 8px 0 0 13px;
  height: 3px;
  border-radius: 2px;
  background: var(--a-border);
  overflow: hidden;
}
.am-bar i {
  display: block;
  height: 100%;
  width: var(--am-share, 0%);
  border-radius: 2px;
  background: rgb(155 230 77 / .333);
  transition: width var(--t-slower) var(--e-out);
}

/* Tag chips: a left-pointing label shape with a punch-hole, per App.axaml's Tag template. */
.am-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 2px; }
.am-tag {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 16px;
  padding: 0 8px 0 14px;
  margin-left: 10px;
  font-size: .625rem;         /* 10px */
  color: var(--a-t2);
  border: 1px solid var(--a-t2);
  border-left: 0;
  border-radius: 0 4px 4px 0;
}
/* The point: a square rotated 45deg with only its lower-left two borders drawn, so the
   two visible edges are the arrowhead's diagonals. 11.3px is 16px/sqrt(2), which makes
   those diagonals land exactly on the box's top and bottom edges. A clipped triangle
   cannot do this — clip-path cuts the border away with the fill. */
.am-tag::before {
  content: "";
  position: absolute;
  left: -5.65px; top: 50%;
  width: 11.3px; height: 11.3px;
  margin-top: -5.65px;
  transform: rotate(45deg);
  border: 1px solid var(--a-t2);
  border-top: 0;
  border-right: 0;
  border-bottom-left-radius: 2px;
  /* ContentControl.Tag.Grey sets Background="Transparent", so the arrowhead shows
     whatever is behind it — the row surface in the list, the composer in the tracker. */
  background: transparent;
}
/* The punch-hole. */
.am-tag::after {
  content: "";
  position: absolute;
  left: 3px; top: 50%;
  width: 3px; height: 3px;
  margin-top: -1.5px;
  border-radius: 50%;
  background: var(--a-t2);
  z-index: 1;
}

/* Switching contexts swaps the MainBar, the project row and the entry list; fade them
   rather than letting the new pane pop in. The switcher itself never moves. */
.am-pane[hidden] { display: none; }
.am-pane.am-swap { animation: am-fade-up var(--t-base) var(--e-out) both; }
@keyframes am-fade-up {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  /* Freeze the sweep partway round rather than removing it — the ring is a picture of a
     running session, so an empty track would read as stopped. */
  .am-ring-arc { animation: none; stroke-dasharray: 105 150.8; }
}

@media (max-width: 640px) {
  .am-titlebar .am-btn { display: none; }
  .am-ctxrow { grid-template-columns: minmax(0, 1fr); }
  .am-readout { font-size: 1.35rem; }
  .am-play { margin: 0 8px; }
  .am-row { grid-template-columns: 3px minmax(0, 1fr) auto 72px auto; padding: 10px 12px; }
  .am-dur { font-size: .8125rem; }
}

/* ==========================================================================
   Code blocks — the SDK section's snippets
   ========================================================================== */

.code {
  margin: 0;
  padding: 1.25rem 1.35rem;
  background: var(--n-950);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  overflow-x: auto;               /* the page body must never scroll sideways */
  font-family: var(--font-mono);
  font-size: .8125rem;
  line-height: 1.75;
  color: var(--text-dim);
  tab-size: 4;
}
.code .c { color: var(--text-faint); }   /* comment */
.code .k { color: var(--accent); }       /* keyword */
.code .t { color: var(--text); }         /* type / member */
.code .s { color: var(--warn); }         /* string */

.code-head {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .6rem 1.35rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-bottom: 0;
  border-radius: var(--r-sm) var(--r-sm) 0 0;
  font-family: var(--font-mono);
  font-size: .75rem;
  color: var(--text-faint);
}
.code-head + .code { border-radius: 0 0 var(--r-sm) var(--r-sm); }
.code-head .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--border-strong); }

/* Inline code inside prose. Scoped to text elements so it never reaches the
   <pre class="code"><code> pair above. */
p code, li code, code.chip {
  padding: .1em .4em;
  border: 1px solid var(--border);
  border-radius: .35rem;
  background: var(--n-900);
  color: var(--text);
  font-size: .875em;
}

/* --- SDK section: slot map and capability list --- */
.slotmap {
  display: grid;
  gap: .5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.slotmap li {
  display: grid;
  grid-template-columns: minmax(7.5rem, auto) 1fr;
  gap: .25rem 1rem;
  padding: .7rem .9rem;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--n-950);
  font-size: .875rem;
  color: var(--text-dim);
}
.slotmap li b {
  font-family: var(--font-mono);
  font-size: .8125rem;
  font-weight: 600;
  color: var(--accent);
}
@media (max-width: 560px) {
  .slotmap li { grid-template-columns: 1fr; }
}

/* A single copyable command — install line, plugin folder path. */
.sdk-cmd {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: .85rem .5rem .85rem 1.35rem;
  margin-bottom: 1.25rem;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--n-950);
}
.sdk-cmd code {
  flex: 1;
  min-width: 0;
  overflow-x: auto;                /* the page body must never scroll sideways */
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: .8125rem;
  color: var(--text);
}
.sdk-cmd .btn { flex: 0 0 auto; }

/* ==========================================================================
   Ring timer — circular indeterminate wait (redeem portal)
   ========================================================================== */

.ring-timer {
  position: relative;
  width: 96px; height: 96px;
  margin: 0 auto;
}
.ring-timer svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ring-timer .ring-bg { fill: none; stroke: var(--border); stroke-width: 4; }
.ring-timer .ring-fg {
  fill: none;
  stroke: var(--accent);
  stroke-width: 4;
  stroke-linecap: round;
  stroke-dasharray: 176;
  stroke-dashoffset: 132;
  animation: ring-spin 1.6s var(--e-in-out) infinite;
  transform-origin: 32px 32px;
}
@keyframes ring-spin {
  0%   { transform: rotate(0deg);   stroke-dashoffset: 154; }
  50%  { transform: rotate(180deg); stroke-dashoffset: 66; }
  100% { transform: rotate(360deg); stroke-dashoffset: 154; }
}
.ring-timer .ring-count {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-family: var(--font-mono);
  font-size: 1.1rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
}

/* ==========================================================================
   Odometer — digits roll into place
   ========================================================================== */

.odometer {
  display: inline-flex;
  overflow: hidden;
  line-height: 1;
  height: 1em;
}
.odo-col {
  display: block;
  width: 1ch;              /* exactly one digit of the monospace face */
  overflow: hidden;
  height: 1em;
}
.odo-col.sep { width: auto; }
.odo-strip {
  display: block;
  transform: translateY(0);
  transition: transform .9s var(--e-out);
  transition-delay: calc(var(--i, 0) * 55ms);
}
/* line-height must be exactly 1 here, or each digit drifts inside its 1em window. */
.odo-strip span { display: block; height: 1em; line-height: 1; }

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 860px) {
  .nav-toggle { display: block; }

  .site-nav {
    position: absolute;
    top: 100%; left: 0; right: 0;
    background: rgb(10 10 10 / .97);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--sh-2);
    /* Collapsed by default; the open state animates the clip + fade. */
    clip-path: inset(0 0 100% 0);
    opacity: 0;
    pointer-events: none;
    transition: clip-path var(--t-base) var(--e-out), opacity var(--t-fast) var(--e-out);
  }
  .site-nav.open { clip-path: inset(0 0 0 0); opacity: 1; pointer-events: auto; }

  .site-nav ul {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: .5rem 1.5rem 1.5rem;
  }
  .site-nav li {
    opacity: 0;
    transform: translateY(-8px);
    transition: opacity var(--t-base) var(--e-out), transform var(--t-base) var(--e-out);
  }
  .site-nav.open li { opacity: 1; transform: none; transition-delay: calc(var(--i, 0) * 55ms + 60ms); }
  .site-nav a { display: block; padding: .85rem 0; border-bottom: 1px solid var(--border); font-size: 1rem; }
  .site-nav a::after { display: none; }

  .header-cta { display: none; }

  .hero { padding-top: 2.5rem; }
  .hero-grid { grid-template-columns: 1fr; gap: 2.5rem; }
  .hero-copy { text-align: center; }
  .hero-copy .hero-sub { margin-left: auto; margin-right: auto; }
  .hero-copy .hero-actions { justify-content: center; }
  .hero-visual { order: -1; }   /* the clock leads on narrow screens */

  .card { padding: 1.5rem; }
  .modal { padding: 1.5rem; }
  .toast-stack { left: 1rem; right: 1rem; }
  .toast { max-width: none; }
}

@media (max-width: 520px) {
  .hero-actions .btn { width: 100%; }
  .footer-inner { justify-content: center; text-align: center; }
}

/* ==========================================================================
   Reduced motion — collapse everything, break nothing.
   Entrance animations must still land on their final state, so this sets
   near-zero durations rather than `animation: none` (which would leave
   opacity:0 elements permanently invisible).
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
    transition-duration: .01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
  html { scroll-behavior: auto; }
  .aurora, .bg-grid { animation: none; }
}
