/* AeloDM canonical design tokens and the one button family.
 *
 * FINAL, ratified 2026-08-26 after four critique rounds and a two round button
 * gallery. Single source of truth for brand color, type, spacing, radii, and the
 * one button family. This file is law; it mirrors design/design-system.html and
 * brand/BRAND_BRIEF.md section 3. It is carried, byte for byte, in both apps that
 * consume it:
 *   - aelodm-landing/static/tokens.css   (imported by style.css)
 *   - saas/frontend/src/tokens.css        (this file, imported by index.css)
 * The Flask landing and the Vite app share no build root, so each keeps a copy.
 * The two copies must stay byte identical. Edit both together and keep them in
 * step with the brand brief and the design system.
 *
 * Canonical gold is #D8A428, taken from the founder's seal (brand/logo, the
 * landing header, and static/favicon.svg all use it). It supersedes the earlier
 * #D9A521 in the brief and #D8B54A in the landing stylesheet.
 *
 * The primary button is gallery variant 9B: Segoe UI weight 700, 0.5px tracking,
 * uppercase 11px regular and 9.5px compact, optically centered with a text-indent
 * equal to the tracking, no icons inside buttons, on the locked gold bar body.
 */

:root {
  /* Core neutrals: cool slate. Roughly 70 percent of any surface. */
  --aelo-slate-obsidian: #0F141A; /* base, darkest: app background, footer */
  --aelo-slate-navy: #12151C;     /* the founder's seal disc, tooltips */
  --aelo-slate-deep: #1A222C;     /* surface: cards, panels, nav rail */
  --aelo-slate-700: #273240;      /* raised surface: hover, elevated cards, quiet buttons */
  --aelo-slate-600: #3A4757;      /* border, divider: hairlines, inputs */
  --aelo-slate-400: #9AA8BA;      /* muted text: metadata, timestamps, brightened per final canon */
  --aelo-slate-100: #E6ECF3;      /* primary text on dark surfaces */
  --aelo-mist: #F3F5F8;           /* light-mode page background */
  --aelo-cloud: #FFFFFF;          /* light-mode cards */

  /* Accent: gold. The one scarce action, a bar of metal, never glossy plastic. */
  --aelo-gold: #D8A428;           /* primary accent: mark, active, hairline base */
  --aelo-gold-bright: #F0C24B;    /* hover on accent, highlights, focus ring */
  --aelo-gold-deep: #A87B12;      /* pressed, primary hairline, accent text on light */
  --aelo-gold-hi: #F7D373;        /* the metallic top sheen on the gold bar */
  --aelo-gold-ink: #241A07;       /* dark warm ink for text on a gold face */
  --aelo-gold-grad: linear-gradient(180deg, #F4CB5B 0%, #D8A428 50%, #BC8C1B 100%);

  /* Support and the visibility canon. Violet DM only, green released, amber hide,
   * red destruction only, blue a neutral callout. Amber is the Hide action and
   * caution color; it is not a visibility state on its own. The word hidden never
   * appears in the UI: a thing is DM Only or Released. */
  --aelo-success: #4FB477;        /* GREEN: released to players, confirmations */
  --aelo-dm: #9F7BFF;             /* VIOLET: DM only, the default resting state */
  --aelo-danger: #D9534F;         /* RED: destruction only (Delete) */
  --aelo-info: #3B9EFF;           /* neutral informational callouts */
  --aelo-warn: #D97742;           /* AMBER: the Hide action, caution, unsaved */

  /* Type stacks. Display serif for titles and brand moments; neutral sans for
   * body and UI; mono for stat blocks and tabular game data. */
  --aelo-font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
  --aelo-font-body: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --aelo-font-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

  /* Type scale. The ratified step sizes and the two line heights for UI and
   * body text. Tokens only; consumers adopt them separately. */
  --aelo-text-xs: 0.72rem;
  --aelo-text-sm: 0.78rem;
  --aelo-text-ui: 0.85rem;
  --aelo-text-body: 0.875rem;
  --aelo-text-lg: 0.95rem;
  --aelo-text-xl: 1.1rem;
  --aelo-text-title: 1.25rem;
  --aelo-leading-ui: 1.45;
  --aelo-leading-body: 1.55;

  /* Spacing scale, 4px base. */
  --aelo-space-1: 0.25rem;
  --aelo-space-2: 0.5rem;
  --aelo-space-3: 0.75rem;
  --aelo-space-4: 1rem;
  --aelo-space-5: 1.5rem;
  --aelo-space-6: 2rem;
  --aelo-space-8: 3rem;

  /* Corner radii. Squared and crisp for the dense DM tool: 4 on controls, 6 on
   * cards and rows, 8 on modals. No toy-like rounding. */
  --aelo-radius-sm: 4px;  /* buttons, inputs, chips */
  --aelo-radius-md: 6px;  /* cards, rows, panels */
  --aelo-radius-lg: 8px;  /* modals, large surfaces */
  --aelo-radius-pill: 999px;

  /* Button density tokens. */
  --aelo-btn-radius: var(--aelo-radius-sm);
  --aelo-btn-pad-y: 0.3rem;
  --aelo-btn-pad-x: 0.7rem;
  --aelo-btn-pad-y-sm: 0.15rem;
  --aelo-btn-pad-x-sm: 0.5rem;
  --aelo-btn-font: 0.85rem;
  --aelo-btn-font-sm: 0.78rem;
  --aelo-btn-weight: 600;
}

/* =========================================================================
   THE ONE BUTTON FAMILY. Primary, secondary, ghost, destructive, icon, plus
   the on-media variant and the sanctioned loud visibility controls. Inventing a
   button, ring, or color outside this set is a defect, not a choice. No icons or
   arrows ever sit inside a button.
   ========================================================================= */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  font-family: var(--aelo-font-body);
  font-size: var(--aelo-btn-font);
  font-weight: var(--aelo-btn-weight);
  line-height: 1.2;
  letter-spacing: 0.01em;
  padding: var(--aelo-btn-pad-y) var(--aelo-btn-pad-x);
  border: 1px solid transparent;
  border-radius: var(--aelo-btn-radius);
  background: transparent;
  color: var(--aelo-slate-100);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.12s ease, border-color 0.12s ease, color 0.12s ease, filter 0.12s ease, transform 0.08s ease;
}
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: 0.55; cursor: default; }

/* Active/pressed toggle state for ghost and secondary buttons used as toggles
   (editor marks, view switches, disclosure rows). Gold text and hairline on a
   quiet raised face, never the loud gold bar. */
.btn.active:not(:disabled) { color: var(--aelo-gold); border-color: var(--aelo-gold-deep); background: var(--aelo-slate-700); }

/* The one focus treatment: a thin 1px gold ring with the subtlest white top
   hint. The sense of gold without weight. */
.btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 1px var(--aelo-gold-bright), inset 0 1px 0 rgba(255, 255, 255, 0.25);
}

/* Primary, the gold bar. Gallery variant 9B. The one scarce call to action, at
   most one per view. Segoe UI 700, 0.5px tracking, uppercase 11px, optically
   centered via text-indent equal to the tracking, no icons. */
.btn--primary {
  justify-content: center;
  padding: 10px 22px;
  border-radius: 4px;
  font-family: 'Segoe UI', 'Segoe UI Semibold', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-indent: 0.5px;
  text-transform: uppercase;
  background: var(--aelo-gold-grad);
  color: var(--aelo-gold-ink);
  border: 1px solid var(--aelo-gold-deep);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 247, 214, 0.45);
}
.btn--primary:hover:not(:disabled) { filter: brightness(1.04); }
.btn--primary:active:not(:disabled) { filter: brightness(0.96); box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3), inset 0 1px 2px rgba(120, 80, 10, 0.4); }
/* Compact gold, the same 9B DNA scaled down for dense contexts: 9.5px caps. */
.btn--primary.btn--sm {
  padding: 7px 15px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-indent: 0.5px;
}

/* Secondary, the quiet workhorse. Slate face, one hairline. */
.btn--secondary { background: var(--aelo-slate-700); color: var(--aelo-slate-100); border-color: var(--aelo-slate-600); }
.btn--secondary:hover:not(:disabled) { border-color: var(--aelo-gold); color: var(--aelo-gold); }

/* Ghost, borderless until hover. For dense toolbars. */
.btn--ghost { background: transparent; color: var(--aelo-slate-400); border-color: transparent; }
.btn--ghost:hover:not(:disabled) { color: var(--aelo-slate-100); border-color: var(--aelo-slate-600); }

/* Destructive, states the color, fills only on hover. Never gold. */
.btn--danger { background: transparent; color: var(--aelo-danger); border-color: var(--aelo-danger); }
.btn--danger:hover:not(:disabled) { background: var(--aelo-danger); color: var(--aelo-slate-obsidian); }

/* Icon, a square ghost holding a single glyph. */
.btn--icon { padding: 0.3rem; width: 2rem; height: 2rem; color: var(--aelo-slate-400); }
.btn--icon:hover:not(:disabled) { color: var(--aelo-slate-100); border-color: var(--aelo-slate-600); }

/* On media, sits over a cover photo. Translucent, keeps squared corners. */
.btn--on-media { background: rgba(0, 0, 0, 0.58); color: #fff; border-color: rgba(255, 255, 255, 0.35); font-size: 0.72rem; padding: 0.2rem 0.6rem; }
.btn--on-media:hover:not(:disabled) { background: rgba(0, 0, 0, 0.72); border-color: #fff; }

/* Size modifier for the non-primary roles. */
.btn--sm { font-size: var(--aelo-btn-font-sm); padding: var(--aelo-btn-pad-y-sm) var(--aelo-btn-pad-x-sm); }

/* Sanctioned loud visibility controls (semantic, not a new button family).
   GREEN releases to players, AMBER takes released content back to DM only. Red is
   reserved for destruction and never appears here. */
.vis-toggle { display: inline-flex; align-items: center; justify-content: center; border: 1px solid transparent; border-radius: var(--aelo-btn-radius); padding: var(--aelo-btn-pad-y) var(--aelo-btn-pad-x); font-family: var(--aelo-font-body); font-size: var(--aelo-btn-font); font-weight: var(--aelo-btn-weight); color: var(--aelo-slate-obsidian); cursor: pointer; white-space: nowrap; }
.vis-release { background: var(--aelo-success); border-color: var(--aelo-success); }
.vis-hide { background: var(--aelo-warn); border-color: var(--aelo-warn); color: #fff; }
.vis-toggle:hover:not(:disabled) { filter: brightness(1.12); }
.vis-toggle:disabled { opacity: 0.55; cursor: default; }

/* Two state visibility segmented control: DM Only / Released. Violet marks the
   DM-only resting state, green marks released. There is no hidden segment. */
.seg { display: inline-flex; border: 1px solid var(--aelo-slate-600); border-radius: var(--aelo-radius-md); overflow: hidden; }
.seg-btn { font: inherit; font-size: 0.82rem; background: var(--aelo-slate-deep); color: var(--aelo-slate-400); border: 0; border-right: 1px solid var(--aelo-slate-600); padding: 0.32rem 0.8rem; cursor: pointer; }
.seg-btn:last-child { border-right: 0; }
.seg-btn:hover { color: var(--aelo-slate-100); }
.seg-btn.active.seg-dm { background: color-mix(in srgb, var(--aelo-dm) 18%, transparent); color: var(--aelo-dm); font-weight: 600; }
.seg-btn.active.seg-player { background: color-mix(in srgb, var(--aelo-success) 18%, transparent); color: var(--aelo-success); font-weight: 600; }
