/* Frenzlo site — shared chrome, built on the app's exported design tokens.
 *
 * Load order matters: fonts.css, tokens.css, then this file.
 * tokens.css and fonts.css are GENERATED (see tools/); this one is authored.
 */

/* ── Compatibility aliases ──────────────────────────────────────────
   The per-page stylesheets were written against `--border` / `--radius`
   before tokens existed. Mapping them onto the real scale re-themes those
   rules in place instead of requiring every page to be rewritten at once.
   New rules should use the token names directly. */
:root {
  /* Card edges, not hairlines. The app draws panel borders with
     `glassBorder` and reserves `divider` for separators inside a list, so
     the alias points at the former — `--divider` stays available for the
     rules that really are separators (`.divider`, `.footer` border-top). */
  --border: var(--glass-border);
  --radius: var(--radius-md);

  /* Status ramps the legal pages defined for themselves before tokens
     existed, re-pointed at the generated washes. Note `--accent-light`
     is deliberately NOT used for these: under the app's palette that
     name means the lighter accent *colour* (#a78bfa), not a tint, and
     page text sitting on it fails contrast. */
  --step-bg: var(--accent-surface);

  --danger: var(--error);
  --danger-light: var(--error-surface);
  --danger-border: var(--error-edge);

  --success-light: var(--success-surface);
  --success-bg: var(--success-surface);
  --success-border: var(--success-edge);

  --warning-bg: var(--warning-surface);
  --warning-border: var(--warning-edge);
  /* The one status value that cannot be a single translucent wash: it is
     foreground text, so it has to invert with the background. */
  --warning-text: #7a4a00;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --warning-text: #f5c97a; }
}
:root[data-theme="dark"] { --warning-text: #f5c97a; }

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

html { -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text-primary);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
  text-wrap: balance;
}

a { color: var(--accent); }

/* Visible focus for keyboard users — the previous pages had none. */
a:focus-visible, button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-xxs);
}

.page {
  max-width: 720px;
  margin: 0 auto;
  padding: var(--space-huge) var(--space-xl) calc(var(--space-huge) * 2);
}

/* ── Ring mark ──────────────────────────────────────────────────────
   The app's F1 launcher mark: 4 concentric rounded squares, no core fill,
   each flipping a full 360° on its own 3D axis. Geometry, colors, stagger
   and axes all come from tokens.css, which is generated from
   `ring_flip_tokens.dart` — the same source the Flutter widget reads.

   Scale by setting --mark-size on the element; everything else follows. */
.ring-mark {
  --mark-size: 34px;
  position: relative;
  display: inline-block;
  flex: none;
  width: var(--mark-size);
  height: var(--mark-size);
  perspective: calc(var(--mark-size) * var(--ring-perspective-ratio));
}

.ring-mark > i {
  position: absolute;
  display: block;
  border-style: solid;
  /* Sub-pixel borders vanish at wordmark scale, so hold a 1px floor. */
  border-width: max(1px, calc(var(--mark-size) * var(--ring-stroke-ratio)));
  transform-style: preserve-3d;
}

.ring-mark > i:nth-child(1) {
  inset: var(--ring-1-inset);
  border-radius: var(--ring-1-radius);
  border-color: var(--ring-1);
}
.ring-mark > i:nth-child(2) {
  inset: var(--ring-2-inset);
  border-radius: var(--ring-2-radius);
  border-color: var(--ring-2);
}
.ring-mark > i:nth-child(3) {
  inset: var(--ring-3-inset);
  border-radius: var(--ring-3-radius);
  border-color: var(--ring-3);
}
.ring-mark > i:nth-child(4) {
  inset: var(--ring-4-inset);
  border-radius: var(--ring-4-radius);
  border-color: var(--ring-4);
}

/* A full 360° returns to the start, so the rest frame is pixel-identical
   to frame 0 — the static mark needs no separate styling. */
@keyframes ring-flip-1 { to { transform: rotate3d(1, 1, 0, 360deg); } }
@keyframes ring-flip-2 { to { transform: rotate3d(0, 1, 0, 360deg); } }
@keyframes ring-flip-3 { to { transform: rotate3d(1, 0, 0, 360deg); } }
@keyframes ring-flip-4 { to { transform: rotate3d(1, -1, 0, 360deg); } }

.ring-mark--spin > i {
  animation-duration: var(--ring-f1);
  animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
  animation-iteration-count: infinite;
}
.ring-mark--spin > i:nth-child(1) {
  animation-name: ring-flip-1;
  animation-delay: var(--ring-1-delay);
}
.ring-mark--spin > i:nth-child(2) {
  animation-name: ring-flip-2;
  animation-delay: var(--ring-2-delay);
}
.ring-mark--spin > i:nth-child(3) {
  animation-name: ring-flip-3;
  animation-delay: var(--ring-3-delay);
}
.ring-mark--spin > i:nth-child(4) {
  animation-name: ring-flip-4;
  animation-delay: var(--ring-4-delay);
}

/* ── Boot loader ────────────────────────────────────────────────────
   Home page only. Paints OVER content that is already in the DOM, so the
   page is complete and readable underneath from the first frame — nothing
   is gated behind this. It dismisses itself via CSS, so a failed or
   disabled script cannot leave a visitor staring at a covered page; the
   inline script only ever makes it leave *sooner*. */
.boot {
  position: fixed;
  inset: 0;
  z-index: 999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ring-stage);
  animation: boot-out 1100ms ease-in forwards;
  /* Never intercept input. The page underneath is complete from the first
     frame, so a click or tap during the fade must reach the real control
     rather than the overlay covering it. */
  pointer-events: none;
}

.boot .ring-mark { --mark-size: 112px; }

@keyframes boot-out {
  0%, 62%  { opacity: 1; visibility: visible; }
  100%     { opacity: 0; visibility: hidden; }
}

/* Set by the inline script once the document is ready. */
.boot--done {
  animation: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 260ms ease-in, visibility 0s linear 260ms;
}

/* ── Wordmark ───────────────────────────────────────────────────────── */
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: var(--space-md);
  margin-bottom: var(--space-huge);
  text-decoration: none;
}
.wordmark-name {
  font-family: var(--font-heading);
  font-size: 18px;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: -0.02em;
}

/* ── Shared chrome ──────────────────────────────────────────────────── */
.page-label, .section-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--space-md);
}

.meta {
  font-size: 13px;
  color: var(--text-tertiary);
  margin-bottom: var(--space-huge);
}

.divider {
  height: 1px;
  background: var(--divider);
  border: 0;
  margin: var(--space-huge) 0;
}

.footer {
  border-top: 1px solid var(--divider);
  padding-top: var(--space-xxl);
  font-size: 13px;
  color: var(--text-tertiary);
}
.footer nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm) var(--space-xl);
  margin-bottom: var(--space-lg);
}
.footer a { text-decoration: none; }
.footer a:hover { text-decoration: underline; }

/* ── Squircle tiles ─────────────────────────────────────────────────
   The launcher's shape language: rounded squares, never circles, at the
   app's `AppRadius.icon(size)` ratio of 22% of the box. */
.tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-lg);
}

.tile {
  background: var(--surface-light);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-lg);
  padding: var(--space-xxl);
}

.tile-icon {
  width: 44px;
  height: 44px;
  border-radius: calc(44px * 0.22);
  background: var(--primary-gradient);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--space-lg);
}
.tile-icon svg { width: 22px; height: 22px; fill: #fff; }

.tile h3 {
  font-size: 16px;
  font-weight: 600;
  margin-bottom: var(--space-sm);
}
.tile p {
  font-size: 14px;
  color: var(--text-secondary);
  line-height: 1.6;
}

/* ── Reduced motion ─────────────────────────────────────────────────
   The rings hold their rest frame and the loader never appears at all —
   an overlay that only exists to play an animation has no reason to be
   shown to someone who has asked not to see animation. */
@media (prefers-reduced-motion: reduce) {
  .ring-mark--spin > i { animation: none; }
  .boot { display: none; }
}

@media (max-width: 480px) {
  .page { padding: var(--space-xxxl) var(--space-lg) var(--space-huge); }
}
