/* ==========================================================================
   Korjin — base layer
   Reset, document defaults, typography roles, shared primitives.
   Components reference semantic tokens only — see tokens.css for the rule.
   ========================================================================== */

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

* {
  margin: 0;
}

/* `hidden` must beat any display value a component sets, or elements toggled
   with el.hidden stay visible AND stay in the a11y tree. Declared once here
   rather than patched per-component. */
[hidden] {
  display: none !important;
}

html {
  /* The overscroll area paints from HTML, not BODY. Without this, dragging the
     page past its top shows whatever html's background is — which on Bottle is
     the platform colour scheme's light background, so a dark-led site flashes
     cream. body's background does not reach that area. */
  background: var(--ground);

  /* The single point where --type-scale becomes real. A percentage (not px)
     so it multiplies the visitor's own browser default rather than replacing
     it, and every rem in every sheet inherits the result. */
  font-size: calc(var(--type-scale) * 100%);
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: var(--leading-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

img {
  height: auto;
}

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

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

a {
  color: inherit;
  text-decoration: none;
}

::selection {
  background: var(--accent-surface);
  color: var(--accent-on);
}

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}

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

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: var(--leading-snug);
  text-wrap: balance;
}

.display {
  font-size: var(--step-6);
  line-height: var(--leading-tight);
  letter-spacing: 0.01em;
}

.title-xl {
  font-size: var(--step-5);
  line-height: 1.08;
}

.title-lg {
  font-size: var(--step-4);
  line-height: 1.12;
}

.title {
  font-size: var(--step-3);
}

.title-sm {
  font-size: var(--step-2);
}

/* Uppercase utility label — eyebrows, nav, buttons, badges. */
.label {
  font-family: var(--font-body);
  font-size: var(--label-size);
  font-weight: 500;
  letter-spacing: var(--label-track);
  text-transform: uppercase;
}

.eyebrow {
  font-family: var(--font-body);
  font-size: var(--label-size);
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--gold-text);
}

.label--gold {
  color: var(--gold-text);
}

.label--accent {
  color: var(--accent-text);
}

.prose {
  max-width: var(--measure);
}

.prose p + p {
  margin-top: var(--sp-4);
}

.muted {
  color: var(--ink-muted);
}

.small {
  font-size: var(--step--1);
}

.num {
  font-variant-numeric: tabular-nums;
}

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

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

.section {
  padding-block: var(--section-y);
}

/* Full-bleed bands — the page's rhythm device. Content inside stays on grid. */
.band-dark {
  background: var(--band-dark);
  color: var(--band-dark-ink);
}

.band-accent {
  background: var(--band-accent);
  color: var(--band-accent-ink);
}

.band-sunken {
  background: var(--ground-sunken);
}

/* Same problem as --band-dark, same answer. Full-bleed, the sunken tone is
   eight units from the dark ground: enough to draw a hard line across the page
   at each edge, not enough to read as a surface. It merges here and takes
   hairlines instead, so the boundary is a line someone drew rather than a step
   someone didn't notice.

   Scoped to the band, not the token — --ground-sunken still does its job on
   small surfaces (image wells, form panels, the mega feature), where a subtle
   step at that scale is exactly right. And left alone on cream, where the
   tonal move is wider and light grounds carry it well. */
:root:not([data-ground="cream"]) .band-sunken {
  background: var(--ground);
  border-block: 1px solid var(--rule);
}

/* Inside a band, muted/faint ink and rules re-resolve against the band ground. */
.band-dark .muted,
.band-accent .muted {
  color: color-mix(in srgb, currentcolor 72%, transparent);
}

.band-dark .eyebrow,
.band-dark .label--gold {
  color: var(--gold-line);
}

/* The oxblood band needs the lifted gold to clear AA — see tokens.css. */
.band-accent .eyebrow,
.band-accent .label--gold {
  color: var(--gold-on-accent);
}

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  /* As a flex ITEM: never shrink below the label. Every CTA row on the site
     pairs a solid button with a quiet link, and under pressure it was the
     solid one that gave — "Start the ritual" broke across two lines while the
     link beside it kept its full width. The row wraps instead (see the page
     sheets). Nothing gives a .btn flex-grow, so this is safe everywhere. */
  flex: none;
  padding: 1.0625rem 1.875rem;
  font-family: var(--font-body);
  font-size: var(--label-size);
  font-weight: 500;
  letter-spacing: var(--label-track);
  text-transform: uppercase;
  border: 1px solid transparent;
  transition: background-color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}

/* Primary: the single most dominant action on any surface (audit UPLIFT-0791). */
.btn--primary {
  background: var(--accent-surface);
  color: var(--accent-on);
}

.btn--primary:hover {
  background: var(--accent-surface-hover);
}

.btn--ink {
  background: var(--ground-inverse);
  color: var(--ink-inverse);
}

.btn--ink:hover {
  background: var(--accent-surface);
  color: var(--accent-on);
}

.btn--ghost {
  border-color: var(--rule-strong);
  color: var(--ink);
}

.btn--ghost:hover {
  border-color: var(--ink);
}

/* Ghost buttons on the oxblood band. The generic ghost border is --rule-strong,
   which measures 1.00:1 against oxblood — invisible (QA-24). A gold hairline
   (--gold-on-accent, 5.3:1) is legible and is what gold is for in the brand
   system. Doubled class so it outranks Shopline's `a:not(.button)` colour rule. */
.band-accent .btn.btn--ghost {
  color: var(--band-accent-ink);
  border-color: var(--gold-on-accent);
}

.band-accent .btn.btn--ghost:hover {
  color: var(--band-accent-ink);
  border-color: var(--band-accent-ink);
  background: color-mix(in srgb, var(--band-accent-ink) 10%, transparent);
}

/* Exempt from the no-shrink rule above. --quiet has no box to protect — it is
   an underlined text link, so it may shrink and wrap like the prose it sits
   in. Held to `flex: none` it pushed 7px past the gutter on the article and
   cart pages at 390px. */
.btn--quiet {
  flex: 0 1 auto;
  padding: 0 0 0.25rem;
  border-bottom: 1px solid currentcolor;
}

/* Hover: brand gold (QA-07). --gold-text is exactly #C5A15F on the dark ground
   and a darker gold on cream (#C5A15F fails contrast there); on the oxblood
   band it switches to the lifted gold, since #C5A15F measures 3.98:1 on
   oxblood. The underline is currentcolor, so it follows. Written as
   `.btn.btn--quiet` because Shopline's base sheet colours
   `a:not(.button):hover` at 0,2,1, which beats a single class + :hover. */
.btn.btn--quiet:hover,
.btn.btn--quiet:focus-visible {
  color: var(--gold-text);
}

.band-accent .btn.btn--quiet:hover,
.band-accent .btn.btn--quiet:focus-visible {
  color: var(--gold-on-accent);
}

.btn[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
}

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */

.field {
  width: 100%;
  padding: 0.9375rem 1.125rem;
  background: transparent;
  border: 1px solid var(--rule-strong);
  color: var(--ink);
  font-size: var(--step--1);
}

.field::placeholder {
  color: var(--ink-faint);
}

/* Border-colour alone is too weak a focus indicator — a 1px hue shift is easy
   to miss. Keep it as reinforcement and let the global :focus-visible ring
   stand. Text inputs match :focus-visible on click too, which is correct here. */
.field:focus {
  border-color: var(--focus);
}

/* One focus line on fields, not two (QA-09). The global :focus-visible ring
   sits 3px outside the element; on a field that already turns its own border
   gold it drew a second rectangle. Pulled onto the border, the two merge into
   a single 2px gold line — still a clear keyboard indicator. */
.field:focus-visible {
  outline-offset: -1px;
}

.field[aria-invalid="true"] {
  border-color: var(--accent-text);
}

.field-error {
  color: var(--accent-text);
  font-size: var(--step--1);
  margin-top: var(--sp-2);
}

/* --------------------------------------------------------------------------
   A11y + motion
   -------------------------------------------------------------------------- */

.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;
}

/* Clipped, not offset. `transform: translateY(-200%)` still leaves the link
   painted just above the viewport, and an overscroll drag brings it into view
   — a pale box appearing out of nowhere at the top of the page. Clipping to a
   1px box removes it from the paint entirely while keeping it focusable, which
   is the standard visually-hidden pattern. */
.skip-link {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  background: var(--ground-inverse);
  color: var(--ink-inverse);
}

.skip-link:focus {
  position: fixed;
  top: var(--sp-3);
  left: var(--sp-3);
  z-index: calc(var(--z-toast) + 1);
  width: auto;
  height: auto;
  margin: 0;
  padding: var(--sp-3) var(--sp-5);
  overflow: visible;
  clip-path: none;
}

/* Scroll-reveal primitives; motion.js flips data-reveal to "in".
   Scoped to .js (set by ground.js) so content is visible by default and only
   hidden when JS is present to reveal it again. Under reduced motion
   everything is simply visible. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
}

.js [data-reveal="in"] {
  opacity: 1;
  transform: none;
}

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

  /* Must match the `.js [data-reveal]` specificity above, or the hidden start
     state keeps winning and reduced-motion users see nothing until JS runs. */
  .js [data-reveal],
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* --------------------------------------------------------------------------
   Phone
   -------------------------------------------------------------------------- */

@media (max-width: 700px) {
  /* 30px of inline padding either side is 60px of a 327px button, and with
     the tracking trim in tokens.css that padding was the remaining reason
     "Explore the full ritual" and "Join the founders circle" still wrapped.
     The vertical padding is untouched — the 44px target comes from it. */
  .btn {
    padding-inline: 1.25rem;
  }

  /* --quiet has no box, so it keeps its own zero-padding rule. */
  .btn--quiet {
    padding-inline: 0;
  }

}
