/* ==========================================================================
   Whitehead Wellness — Reset, typography, and the primitives.
   Mobile first. tokens.css is the vocabulary; this is the grammar.
   ========================================================================== */

/* --- Reset ---------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* No page on a phone-first site scrolls sideways. Ever. If something inside is
     too wide, that is a bug to fix at the source — but it must never present to a
     visitor as a page that slides. */
  overflow-x: clip;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* --- Themed scrollbar ------------------------------------------------------
   A slim antique-gold pill on the ivory page, instead of the OS default grey.
   Lives in base.css, so it themes the public and member pages but NOT the admin
   (which loads only admin.css and stays deliberately unthemed — CLAUDE.md §4).
   The gold is a border/fill here, never text, so the contrast rule is untouched.
   -------------------------------------------------------------------------- */

/* Firefox */
html {
  scrollbar-width: thin;
  scrollbar-color: var(--color-gold) transparent;
}

/* WebKit / Chromium / Safari */
::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  background-color: var(--color-gold);
  border-radius: var(--radius-full);
  /* A ring of page colour around the thumb reads as padding, so the gold sits as
     a slim pill rather than filling the whole gutter. */
  border: 3px solid var(--color-bg);
}

::-webkit-scrollbar-thumb:hover {
  background-color: var(--color-gold-deep);
}

body {
  min-height: 100vh;
  font-family: var(--font-body);
  font-size: var(--text-md);
  line-height: var(--leading-body);
  color: var(--color-text);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img,
picture,
svg,
video {
  display: block;
  max-width: 100%;
  height: auto;
}

/* Lists carry no markers by default. Every list on this site is a layout — a
   nav, a grid of dragons, a set of benefits — and a stray bullet beside a card
   is what a broken list looks like. Prose lists opt back in via .prose. */
ul,
ol {
  list-style: none;
  padding: 0;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: 0;
  cursor: pointer;
}

/* --- Typography ----------------------------------------------------------- */

h1,
h2,
h3,
h4 {
  font-weight: 700;
  line-height: var(--leading-tight);
  letter-spacing: -0.015em;
  text-wrap: balance; /* headlines break at sensible words, not mid-phrase */
}

h1 {
  font-size: var(--text-3xl);
}
h2 {
  font-size: var(--text-2xl);
}
h3 {
  font-size: var(--text-xl);
}
h4 {
  font-size: var(--text-lg);
}

p,
li {
  text-wrap: pretty; /* no single-word last lines */
}

/* Vertical rhythm. Rather than margin-bottom on everything (which then has to be
   un-done at the end of every container), space is owned by the *gap* between
   siblings. Predictable, and it never leaves a dangling margin. */
.flow > * + * {
  margin-top: var(--space-4);
}

.flow > * + h2,
.flow > * + h3 {
  margin-top: var(--space-8);
}

.flow > h2 + *,
.flow > h3 + * {
  margin-top: var(--space-3);
}

/* Long-form reading. Prose lists get their markers back — in a paragraph of
   text, a bullet is meaning, not decoration. */
.prose {
  max-width: var(--width-prose);
}

.prose ul,
.prose ol {
  padding-left: var(--space-6);
}

.prose ul {
  list-style: disc;
}
.prose ol {
  list-style: decimal;
}

.prose li + li {
  margin-top: var(--space-2);
}

.lede {
  font-size: var(--text-lg);
  line-height: var(--leading-snug);
  color: var(--color-text-soft);
  max-width: 46ch;
}

.muted {
  color: var(--color-text-soft);
}

.meta {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
}

/* The label above a thing. Small, quiet, and doing a lot of work. */
.eyebrow {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-soft);
}

/* The script face. A tagline, a vow, a dragon speaking — and nothing else.
   It is never a paragraph, never a button, never a card description. If you are
   reading real information in this typeface, something has gone wrong
   (CLAUDE.md §4). */
.accent-script {
  font-family: var(--font-accent);
  font-size: 1.375em;
  line-height: 1.3;
  color: var(--color-text-soft);
}

.vow {
  font-family: var(--font-accent);
  font-size: var(--text-xl);
  line-height: 1.35;
  color: var(--color-text-soft);
}

/* --- Links ---------------------------------------------------------------- */

a {
  color: var(--color-text);
  text-decoration: underline;
  text-decoration-color: var(--color-gold);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 0.2em;
  border-radius: 2px;
}

a:hover {
  text-decoration-thickness: 2.5px;
}

:focus-visible {
  outline: 2px solid var(--color-gold-deep);
  outline-offset: 2px;
}

.skip-link {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  z-index: 100;
  padding: var(--space-2) var(--space-4);
  background: var(--color-surface);
  border: var(--border-gold);
  border-radius: var(--radius-sm);
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: translateY(0);
}

/* --- Layout primitives ---------------------------------------------------- */

.container {
  width: 100%;
  max-width: var(--width-container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.container--narrow {
  max-width: var(--width-narrow);
}

/* The gold lining around every page (Master Reference §2). A hairline, not a
   frame — it should read as the edge of a page, not the edge of a box. */
.page-lining {
  position: fixed;
  inset: var(--space-2);
  border: 1px solid var(--color-gold-soft);
  border-radius: var(--radius-lg);
  pointer-events: none;
  z-index: 50;
}

@media (max-width: 639px) {
  /* On a phone the lining costs 16px of a 375px screen and buys nothing. */
  .page-lining {
    display: none;
  }
}

/* A section of a page. This is where the breathing room lives. */
.section {
  padding-block: var(--section-gap);
}

.section + .section {
  padding-top: 0;
}

.section__head {
  margin-bottom: var(--space-6);
}

.section__head > * + * {
  margin-top: var(--space-2);
}

.stack > * + * {
  margin-top: var(--space-5);
}

.stack--tight > * + * {
  margin-top: var(--space-3);
}

.stack--loose > * + * {
  margin-top: var(--space-8);
}

.cluster {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}

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

/* --- Buttons -------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--tap-target);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-full);
  font-size: var(--text-base);
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  border: 1.5px solid transparent;
  transition: background var(--duration-fast) var(--ease),
    border-color var(--duration-fast) var(--ease),
    transform var(--duration-fast) var(--ease);
}

.btn:hover {
  text-decoration: none;
  transform: translateY(-1px);
}

.btn:active {
  transform: translateY(0);
}

/* Gold fill, navy ink. The combination that passes AA — gold *on* parchment
   would be 1.9:1, so the fill is what carries the colour, never the letters. */
.btn--primary {
  background: var(--color-gold);
  color: var(--color-text);
  border-color: var(--color-gold);
}

.btn--primary:hover {
  background: var(--color-gold-deep);
  border-color: var(--color-gold-deep);
  color: var(--color-bg);
}

.btn--secondary {
  background: transparent;
  color: var(--color-text);
  border-color: var(--color-line-strong);
}

.btn--secondary:hover {
  border-color: var(--color-gold);
  background: var(--color-gold-wash);
}

.btn--quiet {
  background: transparent;
  border-color: transparent;
  padding-inline: var(--space-3);
  text-decoration: underline;
  text-decoration-color: var(--color-gold);
  text-underline-offset: 0.2em;
}

.btn--block {
  width: 100%;
}

.btn--sm {
  min-height: 36px;
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.5;
  pointer-events: none;
}

/* --- Cards ---------------------------------------------------------------- */

.card {
  display: flex;
  flex-direction: column;
  padding: var(--card-pad);
  background: var(--color-surface);
  border: var(--border-hairline);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}

.card > * + * {
  margin-top: var(--space-3);
}

/* The card's closing call-to-action sits on the FLOOR of the card, not directly
   under the last line of text. Two quests side by side have titles of different
   lengths — one wraps to two lines, one doesn't — and without this their buttons
   land 20px apart from each other, which is the kind of thing you can't unsee. */
.card > p:last-child:has(> .btn) {
  margin-top: auto;
  padding-top: var(--space-4);
}

/* A flex column stretches its children to full width. That is right for a heading
   or a paragraph and wrong for a pill — a badge or a button would go from its own
   shape to a full-bleed bar. Give those back their natural width. */
.card > .badge,
.card > .btn {
  align-self: flex-start;
}

.card--center > .badge,
.card--center > .btn {
  align-self: center;
}

.card__title {
  font-size: var(--text-lg);
}

.card--feature {
  border-color: var(--color-gold-soft);
  box-shadow: var(--shadow-md);
}

/* Everything inside centres — eyebrow, heading, body. A modifier rather than a
   rule on .card itself, because a centred bulleted list (a tier's benefits, a
   dragon's focus areas) reads as a mess: the bullets stop lining up and the eye
   loses the left edge it was tracking. */
.card--center {
  text-align: center;
}

/* text-align centres the LINES. It does nothing for a block that is narrower than
   its parent — and .lede is capped at 46ch, so it was sitting hard against the
   left edge with its lines neatly centred inside it. Centre the box too. */
.card--center .lede,
.card--center .prose {
  margin-inline: auto;
}

.card--center .cluster {
  justify-content: center;
  margin-top: var(--space-8);
}

/* A locked card is never a bare padlock. It says what opens it, and it goes
   somewhere (CLAUDE.md §3). Dashed, quieter, but not greyed into oblivion —
   the thing behind it is still worth wanting. */
.card--locked {
  background: transparent;
  border-style: dashed;
  border-color: var(--color-gold-soft);
  box-shadow: none;
}

/* --- Dragon theming --------------------------------------------------------
   --dragon-color arrives inline from the database. It is a border, a rule, a
   glow — NEVER a text fill. Measured on Warm Parchment:

       Aspen    #B8C6C5   1.6:1   fails
       Valor    #CFAE62   1.9:1   fails
       Rosemary #C68A84   2.6:1   fails
       Kai      #3F6E78   5.1:1   passes

   Six of seven. There is no safe way to write `color: var(--dragon-color)`.
   -------------------------------------------------------------------------- */

.dragon-themed {
  --dragon-color: var(--color-gold); /* fallback, if the DB value is absent */
  border-top: 3px solid var(--dragon-color);
}

/* The pillar name. Navy ink at 9.8:1, with the dragon's colour as a rule beside
   it — the card still reads as *that dragon's* without staking the words on a
   hex we do not control. */
.dragon-accent {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-soft);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

.dragon-accent::before {
  content: "";
  flex: 0 0 auto;
  width: var(--space-6);
  height: 3px;
  border-radius: var(--radius-full);
  /* The fallback lives here rather than being inherited from .dragon-themed —
     these two are independent, and pairing them on one element draws a rule across
     it. A tag with no dragon still gets a dash, in gold. */
  background: var(--dragon-color, var(--color-gold));
}

/* A pillar label directly under somebody's post needs air. In a card its spacing
   comes from `.card > * + *`; a post body has no such rule, so the label sat flush
   against the last line of the member's own words. */
.post__body .dragon-accent {
  margin-top: var(--space-3);
}

/* --- Wells ---------------------------------------------------------------- */

.well {
  padding: var(--space-4);
  background: var(--color-surface-sunk);
  border-radius: var(--radius-sm);
  font-size: var(--text-base);
}

.well--gold {
  background: var(--color-gold-wash);
  border-left: 3px solid var(--color-gold);
}

.well--dragon {
  background: var(--color-surface-sunk);
  border-left: 3px solid var(--dragon-color, var(--color-gold));
}

/* --- Badges --------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0.25em var(--space-3);
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.03em;
  border: 1px solid var(--color-gold);
  background: var(--color-gold-wash);
}

.badge--soft {
  border-color: var(--color-line-strong);
  background: transparent;
  color: var(--color-text-soft);
  font-weight: 600;
}

.badge--done {
  border-color: var(--color-success);
  color: var(--color-success);
  background: transparent;
}

/* --- Grids ---------------------------------------------------------------- */

.grid {
  display: grid;
  gap: var(--space-4);
}

/* Source order matters here and it was wrong.

   The 640px rule for .grid--4 used to sit AFTER the 1024px one. Both match on a
   desktop, later wins, so every four-across grid on the site quietly rendered as
   two columns — the journey paths, the tier previews, all of it. Mobile-first
   means the breakpoints go up in order, always. */
@media (min-width: 640px) {
  .grid--2,
  .grid--3,
  .grid--4 {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1024px) {
  .grid--3 {
    grid-template-columns: repeat(3, 1fr);
  }
  .grid--4 {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* A card in a grid fills its cell. Without this, three cards in a row with
   different amounts of text are three different heights, and a row of ragged
   bottoms is the single most obvious "this was not designed" tell there is.

   `display: grid`, NOT `display: flex`. This took two goes to get right and the
   reason is worth writing down: an <li> in one of these grids is sometimes a
   WRAPPER around a card, and sometimes IS the card (`<li class="panel">`). Flex
   makes its children into a ROW — so on the signup page, the panels rendered as a
   caption with a one-word-wide column of text beside it.

   Grid stacks children in a single column either way, and stretches a lone child
   to fill the cell. It is correct for both shapes.

   A card sitting DIRECTLY in the grid needs nothing at all: grid items already
   stretch. */
.grid > li,
.dragon-grid > li {
  display: grid;
}

/* --- Print ---------------------------------------------------------------- */

@media print {
  .site-header,
  .site-footer,
  .portal-header,
  .portal-footer,
  .page-lining {
    display: none;
  }
}
