/* The shared component vocabulary.
 *
 * The layering is tokens -> components -> pages:
 *
 *   tokens-parchment.css   what the colours, sizes and timings ARE
 *   components.css         what a button, panel, chip and meter ARE  <- here
 *   site.css               the chrome around a page: nav, shell, footer, forms
 *   <page>.css             what is genuinely true of one screen only
 *
 * head.php loads the first three on every page, in that order, so nothing has to
 * opt in. Rules here may use tokens and nothing else — no raw hex, no magic
 * pixel values that a token already names.
 *
 * WHY THIS FILE EXISTS. Before it, every screen re-derived its own panels and
 * chips, so "make the app look like a game menu" meant editing six stylesheets
 * and hoping they agreed. They already did not: the card was written out twice
 * identically in journal.css and quest-builder.css, the chip was spelled three
 * different ways, and the two button systems had drifted apart under a comment
 * telling us to keep them in sync by hand. That comment was the same class of
 * problem as the assets/js/quests.js <-> lib/quests.php mirrors — correct when
 * written, silently wrong later — and it had already gone wrong.
 *
 * WHAT IS AND IS NOT SHARED. Each component below carries only the half its
 * call sites genuinely agree on — the pill radius, the selected state, the
 * frame, the fill. Sizes, paddings and grounds still differ per page and stay
 * in that page's stylesheet, flagged with a comment. Collapsing them would move
 * pixels, and this layer is deliberately introduced without a restyle so the
 * restyle can be judged on its own. Those differences were never decided; they
 * accumulated. The mockups should settle them, and when they do the page-level
 * leftovers disappear into the base here.
 *
 * NAMING. These names are the local half of a contract: the Claude Design
 * system uses the same ones, so a mockup translates into class names rather
 * than guesswork. Do not rename one side alone.
 *
 * Legacy class names appear alongside the new ones as selector aliases, so no
 * markup had to move to introduce this layer. They retire page by page as each
 * screen is restyled.
 */

/* ==========================================================================
   BUTTONS
   One definition, three variants. Previously .ag-btn-* lived in the token file
   and .btn-* lived in site.css, with a hand-maintained "keep in sync" comment
   between them — and they had already drifted: .ag-btn-primary labelled itself
   in --text-on-dark (a token meant for the night band, 5.34:1 on seal) while
   .btn-primary hardcoded #FFF8F0 (6.44:1). The brighter one won, and it has a
   token: --text-on-accent, which is the name the design system's tokens/colors.css
   has used all along. This file briefly called it --text-on-action, which broke
   the one contract the layer exists to keep — that a name means the same thing
   on both sides. Do not rename it on one side alone.
   ========================================================================== */

.ag-parchment .ag-btn-primary,
.ag-parchment .btn-primary,
.ag-parchment .ag-btn-secondary,
.ag-parchment .btn-secondary{
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--font-ui);font-size:var(--fs-md);font-weight:600;
  border-radius:var(--radius-sm);cursor:pointer;text-decoration:none;
}

.ag-parchment .ag-btn-primary,
.ag-parchment .btn-primary{
  background:var(--accent-primary);color:var(--text-on-accent);
  border:none;padding:13px 28px;
  transition:transform var(--dur-fast) var(--ease-standard),
             background var(--dur-fast) var(--ease-standard),
             box-shadow var(--dur-fast) var(--ease-standard);
}
.ag-parchment .ag-btn-primary:hover,
.ag-parchment .btn-primary:hover{
  background:var(--accent-primary-hover);
  transform:var(--lift-hover,translateY(-2px));box-shadow:var(--shadow-action);
}
.ag-parchment .ag-btn-primary:active,
.ag-parchment .btn-primary:active{ background:var(--accent-primary-press);transform:scale(0.985) }
/* .btn-primary never had a disabled state; it does now, by joining this rule. */
.ag-parchment .ag-btn-primary:disabled,
.ag-parchment .btn-primary:disabled{ opacity:0.45;cursor:default;transform:none;box-shadow:none }

.ag-parchment .ag-btn-secondary,
.ag-parchment .btn-secondary{
  background:none;color:var(--text-strong);
  border:1px solid var(--border-default);padding:12px 27px;
  transition:background var(--dur-fast) var(--ease-standard),
             border-color var(--dur-fast) var(--ease-standard);
}
.ag-parchment .ag-btn-secondary:hover,
.ag-parchment .btn-secondary:hover{ background:var(--surface-gold-quiet);border-color:var(--gold-600) }
.ag-parchment .ag-btn-secondary:disabled,
.ag-parchment .btn-secondary:disabled{ opacity:0.45;cursor:default }

/* The quiet variant reads as a link rather than a button: for a real decision
   that should not compete with the primary one beside it ("Leave personal" next
   to Promote and Merge). It was defined in admin.css, which meant a button
   variant lived inside one page's stylesheet. */
.ag-parchment .ag-btn-quiet{
  font-family:var(--font-ui);font-size:var(--fs-sm);
  background:none;border:none;padding:5px 4px;
  color:var(--text-muted);cursor:pointer;
  text-decoration:underline;text-underline-offset:3px;
}
.ag-parchment .ag-btn-quiet:hover{ color:var(--text-body) }
.ag-parchment .ag-btn-quiet:focus-visible{ outline:none;box-shadow:var(--focus-ring);border-radius:var(--radius-sm) }
.ag-parchment .ag-btn-quiet:disabled{ opacity:0.45;cursor:default;text-decoration:none }

/* ==========================================================================
   PANEL / CARD
   A panel is the framed surface. A card is a panel that has agreed to a
   standard padding and a hairline shadow. Six places were re-deriving these
   three declarations; .jr-day and .qb-card were byte-for-byte identical, and
   both spelled their radius as a raw 10px even though --radius-lg is 10px.
   ========================================================================== */

.ag-panel,
.jr-day, .jr-quest, .qb-card, .auth-card, .admin-row, .feature-card{
  background:var(--surface-card);
  border:1px solid var(--border-hairline);
  border-radius:var(--radius-lg);
}

/* Surface variants, mapped to the tokens that already exist. */
.ag-panel--raised{ background:var(--surface-raised) }
/* Applied alongside .ag-panel, so the frame is already there. */
.ag-panel--sunken,
.qb-card-sunken{ background:var(--surface-sunken);box-shadow:none }
/* The full shorthand, not just a colour: --inset is applied to elements that do
   not also carry .ag-panel (the builder's task blocks), so there is no width for
   a bare border-color to tint. */
.ag-panel--inset,
.qb-task{ background:var(--surface-inset);border:1px solid var(--border-rule) }
/* Not a surface so much as an absence of one — used where a row needs the
   panel's shape and spacing but should not read as a raised object. */
.ag-panel--bare,
.admin-row-quiet{ background:transparent }

.ag-card{
  padding:clamp(18px, 3vw, 28px);
  box-shadow:var(--shadow-sm);
}

/* Radii that differ from the base, kept until the restyle settles them.
   --radius-md is the smaller card shape; --radius-sm the tightest. */
.ag-panel--tight,
.feature-card{ border-radius:var(--radius-md) }
.admin-row{ border-radius:var(--radius-sm) }

/* ==========================================================================
   ROW
   The list item, which had three spellings: .card-list li on the guilds page,
   .admin-row in the review queue, and the journal's occurrence rows. What they
   share is a horizontal band with a baseline-aligned gap that wraps rather than
   overflows; what they do not share is their separator, which is why the
   hairline is a modifier rather than part of the base.
   ========================================================================== */

.ag-row{
  display:flex;flex-wrap:wrap;align-items:center;
  gap:var(--space-5);
  min-width:0;
}
.ag-row--baseline{ align-items:baseline }
/* Separated by a rule rather than a gap. The first child loses its border so a
   list does not open with a stray line. */
.ag-row--ruled{ border-top:1px solid var(--border-hairline) }
.ag-row--ruled:first-child{ border-top:0 }

/* ==========================================================================
   CHIP
   A small pill-shaped control that is either on or off. Four call sites had
   invented it separately: the wizard's ability chips, the builder's taker
   chips and day toggles, and the journal's view tabs.

   WHAT IS SHARED IS WHAT IS HERE. The pill radius, the pointer, the resting
   text colour, the hover tell and — the part that was genuinely inconsistent —
   the selected state, which existed as two spellings of near-white (#FFF8F0
   and --parchment-50) on the same seal ground. Both now resolve to
   --text-on-accent.

   WHAT IS NOT SHARED STAYS ON THE PAGE. Size, padding, background and border
   colour still differ per call site, and deliberately are not unified here:
   collapsing them would move pixels, and this layer is being introduced without
   a restyle so that the restyle can be judged on its own. The differences were
   never designed — they accumulated — and the mockups should settle them. Note
   also that .jr-tab is an <a> and the rest are <button>s, so the base must not
   impose a `display`.
   ========================================================================== */

.ag-chip,
.qb-chip, .qb-day, .jr-tab{
  border-radius:var(--radius-pill);
  color:var(--text-body);
  cursor:pointer;
  text-decoration:none;
  transition:background var(--dur-fast) var(--ease-standard),
             border-color var(--dur-fast) var(--ease-standard),
             color var(--dur-fast) var(--ease-standard);
}
.ag-chip:hover,
.qb-chip:hover, .qb-day:hover, .jr-tab:hover{ border-color:var(--gold-600) }

/* On. `.is-selected` is the wizard's spelling and `.is-on` the other three's;
   both are kept because retiring one means editing creation-ui.js. */
.ag-chip.is-selected, .ag-chip.is-on,
.qb-chip.is-on, .qb-day.is-on, .jr-tab.is-on{
  background:var(--accent-primary);
  border-color:var(--accent-primary);
  color:var(--text-on-accent);
}

/* Off, but visible. A chip the current settings rule out is greyed rather than
   hidden, so the rule teaches itself: you can see the option, and the tooltip
   tells you what to widen first. */
.ag-chip.is-off,
.qb-chip.is-off{
  opacity:.42;cursor:not-allowed;
  background:var(--surface-inset);color:var(--text-muted);
  border-color:var(--border-hairline);
}

/* The base's own metrics, for new markup and the gallery. The legacy aliases
   above keep theirs in their page stylesheets until the restyle. */
.ag-chip{
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--font-ui);font-size:var(--fs-xs);
  padding:5px 11px;
  background:transparent;
  border:1px solid var(--border-default);
}

/* ==========================================================================
   BADGE
   A chip's non-interactive twin: a status word, never a control. Promoted out
   of journal.css, where .jr-badge, .jr-occ-skill, .jr-shared and .jr-prog-est
   were four spellings of the same pill. As with the chip, the shared half is
   here and the sizes stay where they are.
   ========================================================================== */

.ag-badge,
.jr-badge, .jr-occ-skill, .jr-shared, .jr-prog-est{
  border-radius:var(--radius-pill);
  background:var(--surface-inset);
  color:var(--text-muted);
  white-space:nowrap;
}
/* The gold variant marks something the Guild itself vouches for — a party
   quest, a canonical skill — and is the one place a badge takes the accent. */
.ag-badge--accent,
.jr-badge-party, .jr-occ-skill, .jr-shared{
  background:var(--surface-gold-quiet);
  color:var(--text-accent);
}
.ag-badge{
  display:inline-flex;align-items:center;
  font-size:var(--fs-3xs);font-weight:600;
  text-transform:uppercase;letter-spacing:.08em;
  padding:3px 9px;
}

/* ==========================================================================
   METER
   A horizontal progress bar. Three existed: .xp-bar on the account page, the
   wizard's .ag-cc-score-bar and the journal's .jr-bar. The first two carried
   the same gold gradient written out as raw hex in two files, bypassing the
   token layer entirely; that gradient is now --fill-meter, which is the real
   win here. Heights and grounds still differ per call site.
   ========================================================================== */

.ag-meter,
.xp-bar, .ag-cc-score-bar, .jr-bar{
  border-radius:var(--radius-pill);
  overflow:hidden;
}
.ag-meter-fill,
.xp-bar-fill, .ag-cc-score-fill{
  height:100%;
  border-radius:var(--radius-pill);
  background:var(--fill-meter);
}
/* The base's own metrics, for new markup and the gallery. Each existing meter
   keeps its height and ground in its page stylesheet — see the note above. */
.ag-meter{ display:block;height:6px;background:var(--surface-sunken) }
.ag-meter-fill,
.xp-bar-fill{ display:block;transition:width var(--dur-slow) var(--ease-standard) }

/* ==========================================================================
   TABS
   A row of chips acting as one choice. The strip is the component; the tabs
   themselves are chips, which is why there is so little here.
   ========================================================================== */

.ag-tabs{ display:flex;flex-wrap:wrap;gap:var(--space-4);margin-bottom:var(--space-7) }

/* ==========================================================================
   UTILITIES
   ========================================================================== */

/* Present to screen readers, absent to everything else. Was in admin.css. */
.visually-hidden{
  position:absolute;
  width:1px;height:1px;
  margin:-1px;padding:0;
  overflow:hidden;
  clip:rect(0 0 0 0);
  white-space:nowrap;
  border:0;
}
