/* ════════════════════════════════════════════════════════════════════════════
   FOUNDRY UI — the Arkaenite Foundry house style, as a reusable kit.

   No build step, no dependency. Drop this <link> on any page and you get the
   tokens + the components below. Compose with classes:

     <div class="af-panel af-panel--pulse"> … carved, glowing card …
     <button class="af-btn af-btn--block">Sign In</button>
     <span class="af-pill af-pill--success">Resolved</span>

   Naming:
     af-thing            a component (a whole "thing" you drop in)
     af-thing--variant   a modifier on that component
     af-util             a single-purpose utility (shape, motif, text)
     is-state            a runtime state toggled by JS (is-active, is-open)

   The motif: a tapered "rune-line" that fades at both ends, with a glowing
   diamond node sitting on it. It marks active/sealed surfaces. Everything in
   here is built from that one idea + the carved-corner panel.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── 1 · Reset ─────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
button, input, select, textarea { font-family: inherit; }

/* ── 2 · Tokens ────────────────────────────────────────────────────────────── */
:root {
  /* Surfaces & ink */
  --bg:       #07030e;
  --surface:  #0b0618;
  --surface2: #110d22;
  --border:   #1e1040;
  --border2:  #2d1a5a;
  --text:     #e4e6ef;
  --text2:    #9ba3b8;
  --text3:    #484f65;

  /* Accents */
  --accent:           #7c3aed;   /* violet — primary */
  --accent-secondary: #d97706;   /* amber — secondary */
  --amber:    #d97706;
  --amber2:   #f5a35a;
  --amber-lit:#fbbf24;
  --success:  #28c87a;
  --danger:   #ff4d6a;

  /* Promoted accent shades (were raw hex scattered through the old CSS) */
  --violet-300: #c4b5fd;   /* light violet — badge names */
  --violet-400: #a78bfa;   /* mid violet — ids, links, type pills */
  --gold-text:  #ffd9a8;   /* warm gold — headings, names, stat values */

  /* Spacing scale — use these on new work instead of magic px numbers */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;

  /* Type */
  --font-display: 'Cormorant Garamond', Georgia, serif;  /* headings, tabs, labels */
  --font-body:    'Spectral', Georgia, 'Times New Roman', serif; /* body + small text */

  /* Shapes — carved silhouettes */
  --chamfer:    polygon(14px 0%, calc(100% - 14px) 0%, 100% 14px, 100% calc(100% - 14px), calc(100% - 14px) 100%, 14px 100%, 0% calc(100% - 14px), 0% 14px);
  --chamfer-sm: polygon(7px 0%, calc(100% - 7px) 0%, 100% 7px, 100% calc(100% - 7px), calc(100% - 7px) 100%, 7px 100%, 0% calc(100% - 7px), 0% 7px);
  /* carved TOP corners only — the panel / modal / active-tab silhouette */
  --carved-top: polygon(14px 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 0 100%, 0 14px);

  /* Motif gradients */
  --rune-line: linear-gradient(90deg, transparent 0%, var(--amber) 22%, var(--amber-lit) 50%, var(--amber) 78%, transparent 100%);
  --lit-below: linear-gradient(180deg, rgba(124,58,237,0.05) 0%, rgba(124,58,237,0.10) 55%, rgba(217,119,6,0.11) 100%);
  --top-glow:  radial-gradient(ellipse 75% 42% at 50% 0%, rgba(124,58,237,0.12), transparent 72%);
}

/* ── 3 · Page chrome ───────────────────────────────────────────────────────── */
/* Put .af-page on <body> to get the dark arcane backdrop + base type. */
.af-page {
  background:
    radial-gradient(ellipse 60% 50% at 8%  5%,  rgba(124,58,237,0.18), transparent),
    radial-gradient(ellipse 50% 40% at 92% 95%, rgba(217,119,6,0.14),  transparent),
    var(--bg);
  background-attachment: fixed;
  color: var(--text);
  font-family: var(--font-body), serif;
  font-size: 16px;
  min-height: 100vh;
}

/* Faint CRT scanline veil over everything. */
.af-scanline::after {
  content: '';
  position: fixed;
  inset: 0;
  background: repeating-linear-gradient(
    0deg,
    transparent 0px, transparent 2px,
    rgba(0,0,0,0.055) 2px, rgba(0,0,0,0.055) 3px);
  pointer-events: none;
  z-index: 9999;
}

/* Themed native scrollbar — styles the real browser scrollbar (no JS, no
   inner-scroll container) so it matches the arcane theme everywhere. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--accent) transparent;
}
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track  { background: transparent; }
::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, var(--accent), var(--amber));
  border: 2px solid var(--bg);   /* inset the thumb from the track edges */
}
::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(180deg, var(--violet-300), var(--amber-lit));
}

/* Drifting embers (positions/sizes are set inline by JS). */
.embers {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 3;
}
.ember {
  --drift: 20px;          /* sideways drift; JS overrides this per ember */
  position: absolute;
  bottom: -6px;
  border-radius: 50%;
  will-change: transform, opacity;
  animation: ember-float linear infinite;
}
@keyframes ember-float {
  0%   { transform: translateY(0) translateX(0); opacity: 0; }
  8%   { opacity: 1; }
  85%  { opacity: 0.55; }
  100% { transform: translateY(-85vh) translateX(var(--drift, 20px)); opacity: 0; }
}
/* Gutter mode — clear the embers out of the central reading column so they only
   drift in the side margins, keeping motion from under the text. Used on reading
   pages (devlog) and on the home page once you've scrolled past the hero. The
   cleared band tracks the .co-wrap column (~1080px); narrower viewports have no
   gutters, so the whole layer fades out. */
.embers--gutter {
  -webkit-mask-image: linear-gradient(90deg,
    #000 0, #000 calc(50% - 600px),
    transparent calc(50% - 560px), transparent calc(50% + 560px),
    #000 calc(50% + 600px), #000 100%);
          mask-image: linear-gradient(90deg,
    #000 0, #000 calc(50% - 600px),
    transparent calc(50% - 560px), transparent calc(50% + 560px),
    #000 calc(50% + 600px), #000 100%);
}

/* ── 4 · Utilities ─────────────────────────────────────────────────────────── */

/* Shape */
.af-chamfer    { clip-path: var(--chamfer); }
.af-chamfer-sm { clip-path: var(--chamfer-sm); }

/* Display-serif headings glow */
.af-glow { text-shadow: 0 0 20px rgba(217,119,6,0.25); }

/* Font role utilities (the small-text-grade serif vs the display serif) */
.af-font-display { font-family: var(--font-display), serif; }
.af-font-body    { font-family: var(--font-body), serif; font-weight: 500; }

/* Screen-reader-only: present in the a11y tree (and to search engines) but
   visually hidden — e.g. an h1 carried by a logo image. */
.af-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Staggered entrance — direct children of .af-stagger cascade in (fade + rise).
   It's self-replaying: the animation re-runs whenever the container goes from
   display:none to shown (e.g. a tab switch) or its children are re-rendered, so
   no JS is needed to retrigger it. Respects prefers-reduced-motion. */
@keyframes af-stagger-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
.af-stagger > * { animation: af-stagger-in 0.45s cubic-bezier(0.16, 1, 0.3, 1) both; }
.af-stagger > *:nth-child(1) { animation-delay: 0.03s; }
.af-stagger > *:nth-child(2) { animation-delay: 0.08s; }
.af-stagger > *:nth-child(3) { animation-delay: 0.13s; }
.af-stagger > *:nth-child(4) { animation-delay: 0.18s; }
.af-stagger > *:nth-child(5) { animation-delay: 0.23s; }
.af-stagger > *:nth-child(6) { animation-delay: 0.28s; }
.af-stagger > *:nth-child(7) { animation-delay: 0.33s; }
.af-stagger > *:nth-child(n+8) { animation-delay: 0.38s; }

/* Branded keyboard focus ring — an amber outline with a soft violet halo, shown
   only for keyboard users (:focus-visible). Mouse clicks never trigger it. The
   `*` rule covers every interactive element; components can override if needed. */
*:focus-visible {
  outline: 2px solid var(--amber-lit);
  outline-offset: 2px;
  border-radius: 1px;
  box-shadow: 0 0 0 4px rgba(124,58,237,0.35), 0 0 12px rgba(217,119,6,0.45);
}
/* Chamfered buttons clip an outer ring away with their carved corners, so they
   wear the ring on the INSIDE instead — it follows the chamfer and stays
   visible. Still keyboard-only (:focus-visible), never on click/hover. */
.af-btn:focus-visible, .af-btn-ghost:focus-visible {
  outline: none;
  box-shadow:
    inset 0 0 0 2px var(--amber-lit),
    inset 0 0 0 5px rgba(124,58,237,0.5);
}
/* Skip-to-content link: an af-sr-only element that surfaces as a styled chip
   when focused, letting keyboard/SR users jump past the nav. */
.af-skip-link:focus {
  position: fixed; top: 12px; left: 12px; z-index: 200;
  width: auto; height: auto; margin: 0; padding: 10px 16px; clip: auto;
  background: var(--surface2); border: 1px solid var(--border2);
  color: var(--gold-text); font-family: var(--font-display), serif; font-size: 15px;
  clip-path: var(--chamfer-sm);
}

/* ─── Rune glyphs ───────────────────────────────────────────────────────────
   Named ornamental marks. Drop one in as an inline symbol — dim by default,
   lit (ember + glow) when it, or an ancestor, has .is-lit (e.g. the active
   tab/nav item). Good for tab indicators, eyebrows, dividers, list markers.
     <span class="af-rune af-rune--orbit"></span>                  (idle/dim)
     <button class="active"><span class="af-rune af-rune--star"></span>…  (lit when JS sets is-lit/active)
*/
.af-rune {
  display: inline-block; line-height: 1;
  color: var(--violet-400); opacity: 0.5;
  transition: color .2s ease, opacity .2s ease, text-shadow .2s ease;
}
.af-rune--ornate::before  { content: "\2756"; }  /* ❖ ornate diamond */
.af-rune--star::before    { content: "\2726"; }  /* ✦ four-point star */
.af-rune--orbit::before   { content: "\27E1"; }  /* ⟡ orbited lozenge */
.af-rune--facet::before   { content: "\25C8"; }  /* ◈ faceted diamond */
.af-rune--diamond::before { content: "\25C6"; }  /* ◆ solid diamond (base mark) */
.af-rune.is-lit, .is-lit .af-rune {
  color: var(--amber); opacity: 1;
  text-shadow: 0 0 8px rgba(217,119,6,0.6);
}

/* ─── Section divider ───────────────────────────────────────────────────────
   A fading amber→violet hairline with a centred glyph. Type the glyph as the
   element's text (it inherits the lit amber styling), or drop in an .af-rune.
   Width/spacing is the page's job.
     <div class="af-divider">❖</div>
*/
.af-divider {
  display: flex; align-items: center; gap: 20px;
  color: var(--amber2); font-size: 16px; line-height: 1;
  text-shadow: 0 0 10px rgba(217,119,6,0.6), 0 0 18px rgba(124,58,237,0.35);
  user-select: none;
}
.af-divider::before, .af-divider::after {
  content: ""; flex: 1; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(217,119,6,0.5) 30%, rgba(124,58,237,0.45) 50%, rgba(217,119,6,0.5) 70%, transparent);
}
/* Lines grow outward FROM the glyph, so each scales from its inner edge. */
.af-divider::before { transform-origin: right center; }
.af-divider::after  { transform-origin: left  center; }

/* Sequenced reveal: the glyph rises into place and shines, THEN the two lines
   draw outward from it, flashing a small glow as they reach full length. Add the
   `is-lit` state (scroll-reveal observer, entrance class, etc.) to play it once.
   Pages own the pre-reveal hidden state (e.g. .reveal opacity:0); this owns the
   choreography. */
@keyframes af-divider-rise {
  0%   { opacity: 0; transform: translateY(9px); text-shadow: none; }
  55%  { opacity: 1; transform: translateY(0);
         text-shadow: 0 0 15px rgba(251,191,36,0.95), 0 0 28px rgba(124,58,237,0.55); }
  100% { opacity: 1; transform: translateY(0);
         text-shadow: 0 0 10px rgba(217,119,6,0.6), 0 0 18px rgba(124,58,237,0.35); }
}
@keyframes af-divider-extend {
  0%   { transform: scaleX(0); filter: none; }
  78%  { transform: scaleX(1); filter: none; }
  88%  { filter: drop-shadow(0 0 5px rgba(251,191,36,0.75)); }   /* tip glow */
  100% { transform: scaleX(1); filter: none; }
}
.af-divider.is-lit          { animation: af-divider-rise 0.6s ease-out both; }
.af-divider.is-lit::before,
.af-divider.is-lit::after   { animation: af-divider-extend 0.5s ease-out 0.5s both; }

/* ─── Timeline ───────────────────────────────────────────────────────────────
   A vertical rune-spine threaded with ❖ nodes — a chronological run of entries
   down a glowing amber→violet line. Reusable for any sequence; the consuming
   page owns spacing and the entries' own content/reveal. Give an item `.is-lit`
   (e.g. when it scrolls into view) to flare its node as it arrives.
     <div class="af-timeline">
       <a class="af-timeline__item">…</a>
       …
     </div>
*/
.af-timeline { position: relative; padding-left: 34px; }
.af-timeline::before {                       /* the spine */
  content: ""; position: absolute; left: 10px; top: 8px; bottom: 8px; width: 2px;
  background: linear-gradient(180deg, transparent, rgba(217,119,6,0.5) 12%, rgba(124,58,237,0.4) 50%, rgba(217,119,6,0.5) 88%, transparent);
}
.af-timeline__item { position: relative; padding-bottom: 34px; }
.af-timeline__item:last-child { padding-bottom: 0; }
.af-timeline__item::before {                 /* the ❖ node on the spine */
  content: "\2756"; position: absolute; left: -31px; top: 3px;
  width: 16px; text-align: center;
  color: var(--amber-lit); font-size: 16px; line-height: 1;
  text-shadow: 0 0 9px rgba(251,191,36,0.7);
}
/* Node shine — a brief flare as the item lands, echoing the divider's glyph. */
@keyframes af-timeline-shine {
  0%, 100% { text-shadow: 0 0 9px rgba(251,191,36,0.7); transform: scale(1); }
  45%      { text-shadow: 0 0 16px rgba(251,191,36,1), 0 0 26px rgba(124,58,237,0.6); transform: scale(1.35); }
}
.af-timeline__item.is-lit::before { animation: af-timeline-shine 0.7s ease-out; }

/* ─── The rune-edge motif ───────────────────────────────────────────────────
   A tapered rune-line along the bottom edge + a diamond node on it. By default
   it rests faint and unlit. Modifiers:
     --lit     always-on "seal" (stat readouts, earned badges, dividers)
     --hover   lights up when the element (or its hover-parent) is hovered
     is-active a JS state that lights it like --lit (e.g. unread markers)
   Tunables (set on the element):
     --rune-inset  how far the line is inset from the sides (default 16px)
*/
.af-rune-edge { position: relative; }
.af-rune-edge::after {
  content: '';
  position: absolute;
  left: var(--rune-inset, 16px);
  right: var(--rune-inset, 16px);
  bottom: 0;
  height: 2px;
  background: var(--rune-line);
  opacity: 0.15;
  box-shadow: none;
  transition: opacity 160ms ease, box-shadow 160ms ease;
  pointer-events: none;
}
.af-rune-edge::before {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -2px;
  width: 6px; height: 6px;
  transform: translateX(-50%) rotate(45deg);
  background: var(--amber-lit);
  opacity: 0;
  box-shadow: none;
  transition: opacity 160ms ease, box-shadow 160ms ease;
  pointer-events: none;
}
/* always-on seal */
.af-rune-edge--lit::after  { opacity: 0.5; box-shadow: 0 0 7px rgba(217,119,6,0.3); }
.af-rune-edge--lit::before { opacity: 1;   box-shadow: 0 0 7px rgba(251,191,36,0.6); }
/* runtime "marked" state (e.g. unread) — line a touch stronger, diamond on */
.af-rune-edge.is-active::after  { opacity: 0.5; box-shadow: 0 0 6px rgba(217,119,6,0.3); }
.af-rune-edge.is-active::before { opacity: 1;   box-shadow: 0 0 6px rgba(251,191,36,0.6); }
/* hover lights the full motif */
.af-rune-edge--hover:hover::after  { opacity: 0.95; box-shadow: 0 0 8px rgba(217,119,6,0.5); }
.af-rune-edge--hover:hover::before { opacity: 1;    box-shadow: 0 0 8px rgba(251,191,36,0.85); }

/* ── 5 · Components ────────────────────────────────────────────────────────── */

/* ─── af-panel — the carved, glowing frame (login card, hub, modal) ──────────
   Top corners are carved; a tapered rune-line rides the top edge. The glow uses
   drop-shadow (not box-shadow) so it follows the carved silhouette instead of
   being clipped. Modifiers:
     --pulse   adds the pulsing diamond node at top-center
     --focal   stronger glow + flush top line (for the focal modal surface)
*/
.af-panel {
  position: relative;
  z-index: 1;
  border: 1px solid rgba(124,58,237,0.38);
  border-radius: 0;
  clip-path: var(--carved-top);
  background: var(--top-glow), var(--surface);
  filter:
    drop-shadow(0 0 32px rgba(124,58,237,0.18))
    drop-shadow(0 18px 34px rgba(0,0,0,0.65));
}
.af-panel::before {
  content: '';
  position: absolute;
  top: var(--panel-line-top, 7px); left: 0; right: 0;
  height: 2px;
  background: var(--rune-line);
  box-shadow: 0 0 10px rgba(124,58,237,0.4);
  z-index: 2;
}
.af-panel--pulse::after {
  content: '';
  position: absolute;
  top: 4px; left: 50%;
  width: 9px; height: 9px;
  transform: translateX(-50%) rotate(45deg);
  background: var(--amber-lit);
  animation: rune-pulse 2.8s ease-in-out infinite;
  z-index: 2;
}
.af-panel--focal {
  --panel-line-top: 0px;
  filter:
    drop-shadow(0 0 36px rgba(124,58,237,0.22))
    drop-shadow(0 22px 44px rgba(0,0,0,0.7));
}

/* ─── af-panel--pulse choreographed reveal ──────────────────────────────────
   A one-shot entrance for a pulse panel: the top diamond shines into place, the
   rune-line draws outward from it (small tip glow at full length), then the box
   (border + glow + background) and its contents materialise. Compose:
     <div class="af-panel af-panel--pulse is-armed" id="x"> … </div>
   `is-armed` holds the hidden pre-state (no flash, no layout shift — content is
   only faded, still laid out). An observer adds `is-revealed` to play it once.
   Works for any pulse panel at any size; direct children fade in together.
   Reduced-motion: the media query at the bottom shows the finished panel. */
.af-panel--pulse.is-armed {
  border-color: transparent;
  background: transparent;
  box-shadow: none;
  filter: none;   /* no skin, no glow, no lift shadow — nothing paints until reveal */
}
/* scaleX(0) alone still smears the line's blurred box-shadow at top-center, so
   kill it too — the keyframe restores it as the line reaches full length. */
.af-panel--pulse.is-armed::before { transform: scaleX(0); transform-origin: center; box-shadow: none; }
.af-panel--pulse.is-armed::after  { opacity: 0; animation: none; }
.af-panel--pulse.is-armed > *     { opacity: 0; }

.af-panel--pulse.is-armed.is-revealed {
  border-color: rgba(124,58,237,0.38);
  background: var(--top-glow), var(--surface);
  filter: drop-shadow(0 0 32px rgba(124,58,237,0.18)) drop-shadow(0 18px 34px rgba(0,0,0,0.65));
  transition: border-color .5s ease .9s, background .5s ease .9s, filter .6s ease .9s;
}
.af-panel--pulse.is-armed.is-revealed::before {
  animation: af-panel-line-extend .55s ease-out .4s both;
}
.af-panel--pulse.is-armed.is-revealed::after {
  animation: af-panel-diamond-reveal .5s ease-out both,
             rune-pulse 2.8s ease-in-out 1s infinite;
}
.af-panel--pulse.is-armed.is-revealed > * {
  opacity: 1; transition: opacity .5s ease 1s;
}
/* line grows from the diamond outward, flashing as it reaches full length. The
   box-shadow stays off until the line is drawn (fill-mode `both` holds the 0%
   frame through the start delay, so no glow smears before it plays). */
@keyframes af-panel-line-extend {
  0%   { transform: scaleX(0); box-shadow: none; filter: none; }
  77%  { transform: scaleX(1); box-shadow: none; filter: none; }
  88%  { box-shadow: 0 0 10px rgba(124,58,237,0.4); filter: drop-shadow(0 0 6px rgba(251,191,36,0.8)); }
  100% { transform: scaleX(1); box-shadow: 0 0 10px rgba(124,58,237,0.4); filter: none; }
}
/* diamond rises + shines, then settles to the rune-pulse resting state */
@keyframes af-panel-diamond-reveal {
  0%   { opacity: 0;   transform: translateX(-50%) translateY(-6px) rotate(45deg) scale(0.6); box-shadow: 0 0 0 rgba(251,191,36,0); }
  60%  { opacity: 1;   transform: translateX(-50%) translateY(0)    rotate(45deg) scale(1.3); box-shadow: 0 0 16px rgba(251,191,36,1), 0 0 26px rgba(124,58,237,0.6); }
  100% { opacity: 0.7; transform: translateX(-50%) translateY(0)    rotate(45deg) scale(1);   box-shadow: 0 0 6px rgba(251,191,36,0.45); }
}

/* ─── af-card / af-entry / af-seal — small surfaces ──────────────────────────
   af-card   a plain inset surface (panel-2 bg + hairline border)
   af-entry  an interactive list row: surface + hover wash + rune-edge that
             lights on hover (compose: class="af-entry", it bundles the motif)
   af-seal   a static surface that wears the rune-edge as a permanent seal
*/
.af-card {
  position: relative;
  background: var(--surface2);
  border: 1px solid var(--border);
}

.af-entry {
  position: relative;
  background: var(--surface2);
  border: 1px solid var(--border);
  transition: background 160ms ease, border-color 160ms ease;
}
.af-entry:not(.is-static):hover {
  background: var(--lit-below);
  border-color: rgba(124,58,237,0.40);
}
/* af-entry carries the rune-edge itself, lighting on hover */
.af-entry::after {
  content: '';
  position: absolute;
  left: var(--rune-inset, 16px); right: var(--rune-inset, 16px); bottom: 0;
  height: 2px;
  background: var(--rune-line);
  opacity: 0.15;
  transition: opacity 160ms ease, box-shadow 160ms ease;
  pointer-events: none;
}
.af-entry::before {
  content: '';
  position: absolute;
  left: 50%; bottom: -2px;
  width: 6px; height: 6px;
  transform: translateX(-50%) rotate(45deg);
  background: var(--amber-lit);
  opacity: 0;
  transition: opacity 160ms ease, box-shadow 160ms ease;
  pointer-events: none;
}
.af-entry:not(.is-static):hover::after  { opacity: 0.95; box-shadow: 0 0 8px rgba(217,119,6,0.5); }
.af-entry:not(.is-static):hover::before { opacity: 1;    box-shadow: 0 0 8px rgba(251,191,36,0.85); }
/* "marked"/unread: persistent medium seal, no hover wash needed */
.af-entry.is-active::after  { opacity: 0.5; box-shadow: 0 0 6px rgba(217,119,6,0.3); }
.af-entry.is-active::before { opacity: 1;   box-shadow: 0 0 6px rgba(251,191,36,0.6); }

.af-seal {
  position: relative;
  background: var(--surface2);
  border: 1px solid var(--border);
}
.af-seal::after {
  content: '';
  position: absolute;
  left: var(--rune-inset, 16px); right: var(--rune-inset, 16px); bottom: 0;
  height: 2px;
  background: var(--rune-line);
  opacity: 0.5;
  box-shadow: 0 0 7px rgba(217,119,6,0.3);
  pointer-events: none;
}
.af-seal::before {
  content: '';
  position: absolute;
  left: 50%; bottom: -2px;
  width: 6px; height: 6px;
  transform: translateX(-50%) rotate(45deg);
  background: var(--amber-lit);
  box-shadow: 0 0 7px rgba(251,191,36,0.6);
  pointer-events: none;
}

/* ─── af-plate — the forged plate card ───────────────────────────────────────
   A heavier, ornamental card: fully chamfered with an etched gradient border,
   corner rivets, a sigil header and a drop-cap title. Distinct from af-card/
   af-seal (which are quiet surfaces) — use this for showpiece content.
   Structure: an outer .af-plate (the etched border) wrapping .af-plate__body.
     <div class="af-plate"><div class="af-plate__body"> … </div></div>
   States: hovers to "awoken" (violet→amber edge); .af-plate--awoken forces it;
   .af-plate--featured is the always-lit hero variant.
*/
.af-plate {
  position: relative;
  padding: 1px;                                  /* the 1px etched border */
  clip-path: var(--chamfer);
  background: linear-gradient(135deg,
    rgba(124,58,237,0.7) 0%, rgba(45,26,90,0.85) 35%,
    rgba(45,42,58,0.8) 50%, rgba(45,26,90,0.85) 65%, rgba(124,58,237,0.7) 100%);
  transition: background .25s ease, filter .25s ease;
}
.af-plate:hover, .af-plate--awoken {
  background: linear-gradient(135deg, var(--accent) 0%, var(--amber) 100%);
  filter: drop-shadow(0 0 12px rgba(124,58,237,0.45));
}
.af-plate--featured {
  background: linear-gradient(135deg, var(--amber) 0%, var(--accent) 50%, var(--amber) 100%);
  filter: drop-shadow(0 0 18px rgba(217,119,6,0.4));
}

.af-plate__body {
  position: relative;
  clip-path: var(--chamfer);
  padding: 22px 24px 20px;
  /* four corner rivets (radial dots) layered over the plate fill — no markup */
  background:
    radial-gradient(circle 5px at 9px 9px,                          var(--amber-lit), var(--amber) 38%, rgba(217,119,6,0.45) 60%, transparent 78%),
    radial-gradient(circle 5px at calc(100% - 9px) 9px,             var(--amber-lit), var(--amber) 38%, rgba(217,119,6,0.45) 60%, transparent 78%),
    radial-gradient(circle 5px at 9px calc(100% - 9px),             var(--amber-lit), var(--amber) 38%, rgba(217,119,6,0.45) 60%, transparent 78%),
    radial-gradient(circle 5px at calc(100% - 9px) calc(100% - 9px),var(--amber-lit), var(--amber) 38%, rgba(217,119,6,0.45) 60%, transparent 78%),
    linear-gradient(180deg, var(--surface2) 0%, var(--surface) 100%);
  background-repeat: no-repeat;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.04), 0 8px 22px rgba(0,0,0,0.45);
}
.af-plate--featured .af-plate__body::before {     /* halo above the featured title */
  content: ''; position: absolute; left: 50%; top: 8px; transform: translateX(-50%);
  width: 44px; height: 18px; pointer-events: none;
  background: radial-gradient(ellipse at center, rgba(217,119,6,0.55), transparent 70%);
}

/* Sigil header — small caps label flanked by fading rune lines */
.af-plate__sigil {
  display: flex; align-items: center; gap: 8px; margin-bottom: 10px;
  font-family: var(--font-body), serif; font-size: 9px; font-weight: 600;
  letter-spacing: 0.32em; text-transform: uppercase; color: var(--amber);
}
.af-plate__sigil::before, .af-plate__sigil::after {
  content: ''; flex: 1; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(217,119,6,0.6) 30%, rgba(217,119,6,0.6) 70%, transparent);
}
.af-plate__sigil .af-rune { opacity: 0.85; }

.af-plate__title {
  font-family: var(--font-display), serif; font-weight: 600; font-size: 18px;
  letter-spacing: 0.04em; color: var(--gold-text); margin: 0 0 6px;
  text-shadow: 0 0 18px rgba(217,119,6,0.35);
}
.af-plate__title::first-letter { font-size: 1.35em; font-weight: 700; color: var(--amber); }
.af-plate--featured .af-plate__title { font-size: 24px; color: #e9defc; text-shadow: 0 0 22px rgba(124,58,237,0.5); }
.af-plate--featured .af-plate__title::first-letter { color: var(--violet-300); }

.af-plate__text { font-family: var(--font-body), serif; font-size: 13px; line-height: 1.6; color: var(--text2); margin: 0; }

/* Optional featured ornaments */
.af-plate__tag {
  position: absolute; top: 16px; right: 20px;
  font-family: var(--font-body), serif; font-size: 9px; letter-spacing: 0.16em; color: var(--violet-400);
}
.af-plate__inscription {
  position: absolute; left: 8px; top: 50%; transform: translateY(-50%) rotate(180deg);
  writing-mode: vertical-rl;
  font-family: var(--font-body), serif; font-size: 8px; letter-spacing: 0.4em; color: rgba(176,148,255,0.5);
}

/* ─── af-btn — the runed primary button ─────────────────────────────────────
   Base is a violet gradient on a chamfered slab that turns amber on hover.
   Modifiers:
     --block  full-width, lifts on hover, wears ◆ corner glyphs (form submits)
     --sm     compact inline size (inline submits)
   Ghost variant (af-btn-ghost) is the outline button.
*/
.af-btn {
  display: inline-block;
  background: linear-gradient(135deg, rgba(124,58,237,0.95) 0%, rgba(100,30,210,0.95) 100%);
  border: none;
  border-radius: 0;
  clip-path: var(--chamfer-sm);
  padding: 9px 20px;
  font-size: 12px;
  font-weight: 600;
  font-family: var(--font-display), serif;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold-text);
  cursor: pointer;
  position: relative;
  transition: all 0.2s ease-out;
  box-shadow: 0 0 14px rgba(124,58,237,0.3);
}
.af-btn:hover:not(:disabled) {
  background: linear-gradient(135deg, #b45309 0%, #d97706 100%);
}
.af-btn:disabled { opacity: .45; cursor: default; }

.af-btn--block {
  width: 100%;
  padding: 14px 10px;
  font-size: 14px;
  letter-spacing: 0.16em;
  overflow: visible;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.08),
    inset 0 -1px 0 rgba(0,0,0,0.3),
    0 0 20px rgba(124,58,237,0.38);
}
.af-btn--block::before,
.af-btn--block::after {
  content: "◆";
  position: absolute;
  font-size: 7px;
  color: #f5a35a;
  top: 6px;
  pointer-events: none;
}
.af-btn--block::before { left: 8px; }
.af-btn--block::after  { right: 8px; }
.af-btn--block:not(:disabled):hover {
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.15),
    0 8px 24px rgba(217,119,6,0.42),
    0 0 30px rgba(217,119,6,0.45);
}

.af-btn--sm { padding: 9px 20px; font-size: 12px; }

/* Secondary "tonal" button. A soft violet fill on the same chamfer as the
   primary — so the cut corners read as a finished solid shape, not stray lines.
   Clearly a lower tier than .af-btn: muted, flat, no ◆ corners, no amber. */
.af-btn-ghost {
  display: inline-block;
  background: rgba(124,58,237,0.14);
  border: none;
  border-radius: 0;
  clip-path: var(--chamfer-sm);
  color: var(--violet-300);
  font-family: var(--font-display), serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  padding: 6px 14px;
  cursor: pointer;
  white-space: nowrap;
  transition: background .2s ease, color .2s ease, filter .2s ease;
}
.af-btn-ghost:hover {
  background: rgba(124,58,237,0.26);
  color: #e9defc;
  filter: drop-shadow(0 0 8px rgba(124,58,237,0.4));
}

/* Underlined text button (links, "show more") */
.af-link {
  background: none;
  border: none;
  color: var(--text3);
  font-size: 13px;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color .15s;
  width: auto;
}
.af-link:hover { color: var(--text2); }

/* ─── af-pill — small status / type chips ───────────────────────────────────
   Base is an uppercase body-serif chip. Color variants:
     --success  green (resolved/claimed)
     --active   amber (in-progress)
     --neutral  muted (open/meta)
     --violet   violet (type)
   Size: --xs for the tighter notification chips.
*/
.af-pill {
  display: inline-block;
  font-family: var(--font-body), serif;
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 4px 9px;
  white-space: nowrap;
  border: 1px solid transparent;
  vertical-align: middle;
}
.af-pill--success { background: rgba(40,200,122,0.10); color: var(--success);   border-color: rgba(40,200,122,0.28); }
.af-pill--active  { background: rgba(217,119,6,0.12);  color: var(--amber2);    border-color: rgba(217,119,6,0.30); }
.af-pill--neutral { background: var(--surface2);       color: var(--text3);     border-color: var(--border2); }
.af-pill--violet  { background: rgba(124,58,237,0.10); color: var(--violet-400);border-color: rgba(124,58,237,0.25); }
.af-pill--xs      { padding: 2px 6px; letter-spacing: 0.10em; }

/* ─── af-input / af-textarea — runed fields ─────────────────────────────────── */
.af-input, .af-textarea {
  width: 100%;
  background: var(--surface2);
  border: 1px solid var(--border2);
  border-left: 2px solid rgba(124,58,237,0.4);
  border-radius: 0;
  padding: 9px 12px;
  font-size: 15px;
  color: var(--text);
  outline: none;
  transition: border-color .15s, border-left-color .15s;
  -webkit-appearance: none;
}
.af-textarea { font-size: 14px; resize: vertical; min-height: 72px; }
.af-input:focus, .af-textarea:focus {
  border-color: rgba(124,58,237,0.65);
  border-left-color: var(--amber);
}
.af-input::placeholder, .af-textarea::placeholder { color: var(--text3); }

/* ─── af-section — section header with extending rule ───────────────────────── */
.af-section {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 24px;
  margin-bottom: 10px;
}
.af-section__title {
  font-family: var(--font-body), serif;
  font-weight: 500;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--amber2);
  white-space: nowrap;
}
.af-section__rule {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, rgba(217,119,6,0.25) 0%, transparent 100%);
}
.af-section__count {
  font-family: var(--font-body), serif;
  font-weight: 500;
  font-size: 12px;
  color: var(--text3);
}

/* ── 6 · Motion ────────────────────────────────────────────────────────────── */
@keyframes rune-pulse {
  0%, 100% { opacity: 0.7; box-shadow: 0 0 6px rgba(251,191,36,0.45); }
  50%      { opacity: 1;   box-shadow: 0 0 15px rgba(251,191,36,0.95), 0 0 24px rgba(124,58,237,0.5); }
}
@keyframes arcane-shake {
  0%, 100% { transform: translateX(0); }
  18% { transform: translateX(-7px); }
  36% { transform: translateX(7px); }
  54% { transform: translateX(-4px); }
  72% { transform: translateX(4px); }
  90% { transform: translateX(-1px); }
}
.af-shake { animation: arcane-shake 0.42s ease-out; }

/* Kill all motion for users who ask for it — one rule, zero exceptions */
@media (prefers-reduced-motion: reduce) {
  .af-shake,
  .af-panel--pulse::after,
  .af-divider.is-lit,
  .af-divider.is-lit::before,
  .af-divider.is-lit::after,
  .af-timeline__item.is-lit::before,
  .af-panel--pulse.is-armed.is-revealed::before,
  .af-panel--pulse.is-armed.is-revealed::after,
  .af-stagger > *,
  .hub-entering { animation: none !important; }
  .embers { display: none; }   /* drop the drifting embers (and their GPU layers) entirely */
  /* Choreographed pulse panel: show the finished box outright. */
  .af-panel--pulse.is-armed {
    border-color: rgba(124,58,237,0.38);
    background: var(--top-glow), var(--surface);
    filter: drop-shadow(0 0 32px rgba(124,58,237,0.18)) drop-shadow(0 18px 34px rgba(0,0,0,0.65));
  }
  .af-panel--pulse.is-armed::before { transform: none; box-shadow: 0 0 10px rgba(124,58,237,0.4); }
  .af-panel--pulse.is-armed::after  { opacity: 0.7; }
  .af-panel--pulse.is-armed > *     { opacity: 1; }
}
