/* ==========================================================================
   Carbon Hosting component stylesheet (dark theme only)
   Source of truth: BRAND-KIT.md, implemented on tokens.css.
   Scope: the complete kit. Every named component of the shared blade kit
   styles from this file, strictly on token variables.

   Rules kept in this file:
   - Dark only: no theme switch and no prefers color scheme query anywhere
     (tokens.css already owns the dark re assertion guard).
   - Color values come exclusively from token variables via var(), never as
     literal hex, never as literal near white or near black utility tints.
   - Interactive elements keep 44px minimum hit height and width (kit 0.1.5,
     5.4); the hit area carries the rule, not the visual box.
   - Motion: transform and opacity only, on the motion tokens; the reduced
     motion collapse lives in tokens.css and applies to everything.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Container, section rhythm and page furniture (kit 5.1)
   -------------------------------------------------------------------------- */

.ch-container {
  box-sizing: border-box;
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-4);
}

@media (min-width: 768px) {
  .ch-container {
    padding-inline: var(--space-6);
  }
}

.ch-container-narrow {
  max-width: 72ch;
}

/* The section rhythm law (owner order 2026-10-16): 32px of vertical air
   on mobile and 48px on desktop at every section gap edge; hero bottom
   margins stay under 40px (32px); card grid gaps hold 16 to 24; and no
   rule in this file ever shrinks the padding inside an interactive
   control (the 44px floors are law, not spacing candidates). */
.ch-section {
  padding-block: var(--space-8);
}

@media (min-width: 768px) {
  .ch-section {
    padding-block: var(--space-9);
  }
}

/* Band spacing: the hero and page top surfaces. The band breathes wider
   on top on desktop, while its bottom edge (the hero bottom margin of
   record) never grows past 40px: it holds 32px on every viewport. */
.ch-section-band {
  padding-top: var(--space-8);
  padding-bottom: var(--space-8);
}

@media (min-width: 768px) {
  .ch-section-band {
    padding-top: var(--space-9);
    padding-bottom: var(--space-8);
  }
}

/* --------------------------------------------------------------------------
   Typography classes (kit 4.2): fixed scale steps on token pairs, plus the
   uppercase display treatment and the tabular numerals utility (kit 4.3).
   The display 1 ramp steps through its kit roles: mobile H1 (display 3
   size), tablet (display 2), desktop 1280px and up (display 1).
   -------------------------------------------------------------------------- */

.ch-display-1,
.ch-display-2,
.ch-display-3,
.ch-display-4,
.ch-title-1,
.ch-title-2 {
  font-family: var(--font-display);
  color: var(--text-primary);
  margin: 0;
}

.ch-display-1 {
  font-size: var(--fs-display-3);
  line-height: var(--lh-display-3);
  font-weight: var(--fw-bold);
}

@media (min-width: 768px) {
  .ch-display-1 {
    font-size: var(--fs-display-2);
    line-height: var(--lh-display-2);
  }
}

@media (min-width: 1280px) {
  .ch-display-1 {
    font-size: var(--fs-display-1);
    line-height: var(--lh-display-1);
  }
}

.ch-display-2 {
  font-size: var(--fs-display-4);
  line-height: var(--lh-display-4);
  font-weight: var(--fw-bold);
}

@media (min-width: 768px) {
  .ch-display-2 {
    font-size: var(--fs-display-3);
    line-height: var(--lh-display-3);
  }
}

@media (min-width: 1280px) {
  .ch-display-2 {
    font-size: var(--fs-display-2);
    line-height: var(--lh-display-2);
  }
}

.ch-display-3 {
  font-size: var(--fs-display-3);
  line-height: var(--lh-display-3);
  font-weight: var(--fw-bold);
}

.ch-display-4 {
  font-size: var(--fs-display-4);
  line-height: var(--lh-display-4);
  font-weight: var(--fw-semibold);
}

.ch-title-1 {
  font-size: var(--fs-title-1);
  line-height: var(--lh-title-1);
  font-weight: var(--fw-semibold);
}

.ch-title-2 {
  font-size: var(--fs-title-2);
  line-height: var(--lh-title-2);
  font-weight: var(--fw-semibold);
}

.body-copy,
.ch-body-lg,
.ch-body-base,
.ch-body-sm,
.ch-caption,
.ch-eyebrow {
  font-family: var(--font-body);
  margin: 0;
}

.ch-body-lg {
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body);
  font-weight: var(--fw-regular);
  color: var(--text-secondary);
}

.ch-body-base {
  font-size: var(--fs-body-base);
  line-height: var(--lh-body);
  font-weight: var(--fw-regular);
  color: var(--text-secondary);
}

.ch-body-sm {
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  font-weight: var(--fw-regular);
  color: var(--text-secondary);
}

.ch-caption {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
}

.ch-eyebrow {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
  color: var(--text-secondary);
}

.ch-uppercase {
  text-transform: uppercase;
  letter-spacing: var(--track-uppercase);
}

/* Uppercase belongs to display headings; body copy never sets uppercase. */
p.ch-uppercase,
li.ch-uppercase {
  text-transform: none;
  letter-spacing: normal;
}

.ch-nums {
  font-variant-numeric: var(--numeric-variant);
}

/* Text links inside copy: accent tier, underline kept deliberate. The
   link stays an inline text box so the surrounding sentence keeps its
   single spaces and the sentence period attaches to the text (an atomic
   inline flex box read as widened word gaps with a floating period).
   The 44px hit floor rides the pseudo hit band instead: the hit area
   carries the rule, not the visual box. */
.ch-link {
  position: relative;
  display: inline;
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.ch-link::after {
  content: "";
  position: absolute;
  /* The band offsets resolve against the inline anchor's own fragment
     box, so a link that wraps mid text carries the band on its first
     fragment only; every current use is a one line short link. The
     offsets keep the band 48px or taller at the smallest caption size
     (12px text area plus the 36px band). */
  top: -18px;
  bottom: -18px;
  left: calc(var(--space-2) * -1);
  right: calc(var(--space-2) * -1);
  border-radius: var(--radius-xs);
}

.ch-link:hover {
  color: var(--accent-hover);
}

.ch-link:focus-visible {
  box-shadow: var(--focus-ring);
  outline: none;
  border-radius: var(--radius-xs);
}

/* --------------------------------------------------------------------------
   Shell: header (kit 5.8) and campaign banner slot
   -------------------------------------------------------------------------- */

.ch-header {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: var(--bg-raised);
  border-bottom: 1px solid var(--border-1);
}

.ch-header-row,
.ch-banner-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.ch-header-row {
  min-height: 56px;
}

@media (min-width: 1024px) {
  .ch-header-row {
    min-height: 64px;
  }
}

.ch-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 44px;
  color: var(--text-primary);
  text-decoration: none;
  font-family: var(--font-display);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-body-base);
}

.ch-brand:hover {
  color: var(--text-primary);
}

.ch-brand:focus-visible {
  box-shadow: var(--focus-ring);
  outline: none;
  border-radius: var(--radius-sm);
}

.ch-brand img {
  height: 28px;
  width: auto;
  display: block;
}

.ch-nav {
  display: none;
  align-items: center;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 1024px) {
  .ch-nav {
    display: flex;
  }
}

.ch-nav-link {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-3);
  min-height: 44px;
  color: var(--text-secondary);
  font-family: var(--font-body);
  font-weight: var(--fw-medium);
  font-size: var(--fs-body-base);
  text-decoration: none;
  border-radius: var(--radius-xs);
  transition: color var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out);
}

.ch-nav-link:hover {
  color: var(--text-primary);
  background: var(--tint-hairline);
}

.ch-nav-link:focus-visible {
  box-shadow: var(--focus-ring);
  outline: none;
}

/* Active entry: accent tint fill with accent text (kit 3.9 selected row). */
.ch-nav-link[aria-current="page"] {
  color: var(--accent);
  background: var(--accent-tint-2);
}

.ch-menu-trigger,
.ch-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  color: var(--text-primary);
  background: transparent;
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out);
}

.ch-menu-trigger:hover,
.ch-icon-btn:hover {
  background: var(--tint-hairline);
}

.ch-menu-trigger:focus-visible,
.ch-icon-btn:focus-visible {
  box-shadow: var(--focus-ring);
  outline: none;
}

@media (min-width: 1024px) {
  .ch-menu-trigger {
    display: none;
  }
}

.ch-header-actions {
  display: none;
  align-items: center;
  gap: var(--space-3);
}

@media (min-width: 1024px) {
  .ch-header-actions {
    display: flex;
  }
}

/* Account entry in the header (one login doctrine, kit 5.8): the
   identity lines sit on the account link, the panel entry and the
   sign out pair beside it. Forms inside the row render inline so the
   flex row keeps its shape. */
.ch-header-account {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.ch-header-account form {
  display: inline-flex;
}

.ch-account-entry {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-height: 44px;
  max-width: 220px;
  padding: 0 var(--space-2);
  color: var(--text-primary);
  text-decoration: none;
  border-radius: var(--radius-sm);
  transition: background-color var(--dur-fast) var(--ease-out);
}

.ch-account-entry:hover {
  background: var(--tint-hairline);
}

.ch-account-entry:focus-visible {
  box-shadow: var(--focus-ring);
  outline: none;
}

.ch-account-name {
  font-family: var(--font-body);
  font-weight: var(--fw-medium);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ch-account-email {
  font-family: var(--font-body);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Campaign banner slot above the header (kit 5.8): honest dated promos
   only, dismissible. Always real data or nothing. */
.ch-banner {
  background: var(--tint-2);
  border-bottom: 1px solid var(--border-1);
}

.ch-banner-inner {
  min-height: 44px;
  padding-block: var(--space-2);
}

.ch-banner-copy {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  color: var(--text-secondary);
}

.ch-banner-text {
  min-height: 24px;
  display: inline-flex;
  align-items: center;
}

/* --------------------------------------------------------------------------
   Skip link (accessibility posture of kit 0 and section 5)
   -------------------------------------------------------------------------- */

.ch-skip-link {
  position: absolute;
  top: var(--space-4);
  left: var(--space-4);
  z-index: var(--z-toast);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--space-4);
  background: var(--bg-modal);
  color: var(--text-primary);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-md);
  text-decoration: none;
  transform: translateY(calc(-100% - var(--space-4)));
  pointer-events: none;
}

.ch-skip-link:focus-visible {
  transform: none;
  pointer-events: auto;
  box-shadow: var(--focus-ring);
  outline: none;
}

/* Buttons (kit 5.4: 44px hit minimum everywhere,
   labels 20px display face weight 600, gap 8px to an icon, padding 20px).
   The border box sizing of record: at width 100% inside a padded slot
   (card CTA zones, form columns) the padding must stay inside the
   declared width, never outside it. */

.ch-btn {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 44px;
  height: 48px;
  padding: 0 var(--space-5);
  border: none;
  border-radius: var(--radius-md);
  font-family: var(--font-display);
  font-size: var(--fs-title-2);
  line-height: 1.2;
  font-weight: var(--fw-semibold);
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}

.ch-btn:focus-visible {
  box-shadow: var(--focus-ring);
  outline: none;
}

.ch-btn:active {
  transform: translateY(1px);
}

.ch-btn-primary {
  background: var(--accent);
  color: var(--text-on-accent);
}

.ch-btn-primary:hover {
  background: var(--accent-hover);
  box-shadow: var(--bloom-accent);
}

.ch-btn-primary:active {
  background: var(--accent-active);
  box-shadow: none;
}

.ch-btn-secondary {
  background: transparent;
  border: 1px solid var(--border-2);
  color: var(--text-primary);
}

.ch-btn-secondary:hover {
  background: var(--tint-3);
  border-color: var(--border-2);
}

.ch-btn-secondary:active {
  background: var(--tint-4);
}

.ch-btn-ghost {
  background: transparent;
  color: var(--text-secondary);
}

.ch-btn-ghost:hover {
  background: var(--tint-hairline);
  color: var(--text-primary);
}

.ch-btn-ghost:active {
  background: var(--tint-soft);
}

.ch-btn-danger {
  background: var(--danger);
  color: var(--text-on-accent);
}

.ch-btn-danger:hover {
  box-shadow: var(--ring-danger);
}

.ch-btn-danger:active {
  box-shadow: none;
}

.ch-btn[disabled],
.ch-btn[aria-disabled="true"] {
  background: var(--tint-hairline);
  border: 1px solid var(--border-1);
  color: var(--text-disabled);
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
}

/* Icon only buttons are square 44 by 44 and always carry an accessible
   name in markup. */
.ch-btn-icon {
  height: 44px;
  width: 44px;
  min-width: 44px;
  padding: 0;
}

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

/* --------------------------------------------------------------------------
   Cards and cards bands (kit 5.5 anatomy zones and 5.3 elevation)
   -------------------------------------------------------------------------- */

.ch-card {
  background: var(--surface-card);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-md);
  transition: transform var(--dur-base) var(--ease-out);
}

.ch-card:hover {
  transform: translateY(-2px);
}

.ch-card:focus-visible {
  box-shadow: var(--focus-ring);
  outline: none;
}

a.ch-card {
  display: block;
  color: var(--text-secondary);
  text-decoration: none;
}

a.ch-card:hover,
a.ch-card:focus-visible {
  color: var(--text-secondary);
}

a.ch-card:focus-visible,
.ch-card-featured:focus-visible {
  border-color: var(--accent);
}

/* Featured card: ember glow edge wash, never a bigger box (kit 5.5). */
.ch-card-featured {
  box-shadow: 0 0 0 1px var(--glow-ember-strong), var(--shadow-md);
}

/* Notice card: a card surface with a semantic left edge (the checkout
   notice treatment). Static information tier only: it never carries
   urgency styling, counts, or countdowns of any kind. */
.ch-notice-warning {
  border-left: var(--space-1) solid var(--warning);
}

.ch-card-title {
  font-family: var(--font-display);
  font-size: var(--fs-title-1);
  line-height: var(--lh-title-1);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  margin: 0 0 var(--space-2);
}

.ch-card-copy {
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  color: var(--text-secondary);
  margin: 0;
}

.ch-cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

@media (min-width: 768px) {
  .ch-cards {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-6);
  }
}

/* --------------------------------------------------------------------------
   Media blocks for card imagery (kit 7 art direction, 16/9 covers)
   -------------------------------------------------------------------------- */

.ch-media {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-1);
  background: var(--surface-sunken);
  aspect-ratio: 16 / 9;
}

.ch-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* --------------------------------------------------------------------------
   Chips and status (kit 5.9)
   -------------------------------------------------------------------------- */

.ch-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 28px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-full);
  border: 1px solid var(--border-1);
  background: var(--tint-2);
  color: var(--text-secondary);
  font-family: var(--font-body);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  text-decoration: none;
}

.ch-chip-accent {
  background: var(--accent-tint-2);
  color: var(--accent);
}

.ch-chip-ember {
  background: var(--ember-tint-1);
  color: var(--accent-2);
}

/* Topic badge chips (knowledge base rows, 2026-10-16 fix pass): on every
   card surface the badge is the last element after the copy, so the
   badge carries visible top spacing against the text above it instead
   of sitting flush. Non interactive chip; the 44px rule does not apply. */
.ch-chip-topic {
  margin-top: var(--space-3);
}

/* Status chips: semantic text on transparent fills (kit 5.9), dot or icon
   beside the label so color is never the only signal. */
.ch-chip-success {
  background: transparent;
  color: var(--success);
}

.ch-chip-warning {
  background: transparent;
  color: var(--warning);
}

.ch-chip-danger {
  background: transparent;
  color: var(--danger);
}

.ch-chip-info {
  background: transparent;
  color: var(--info);
}

/* Chips used as interactive elements carry the 44px hit rule. */
.ch-chip-link,
a.ch-chip {
  min-height: 44px;
  padding: 0 var(--space-4);
}

a.ch-chip:hover {
  background: var(--tint-3);
  color: var(--text-primary);
}

.ch-chip-accent-link {
  background: var(--accent-tint-2);
  color: var(--accent);
}

a.ch-chip-accent-link:hover {
  background: var(--accent-tint-3);
  color: var(--accent);
}

a.ch-chip-accent-link:focus-visible,
a.ch-chip:focus-visible,
.ch-chip-link:focus-visible {
  box-shadow: var(--focus-ring);
  outline: none;
}

a.ch-chip-accent-link:active,
a.ch-chip:active,
.ch-chip-link:active {
  background: var(--accent-tint-4);
}

/* Counter chip: raised fill, hairline border, live dot; numbers come from
   real backend values only, a dash renders when nothing is measured yet. */
.ch-chip-counter {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--border-1);
  background: var(--bg-raised);
  color: var(--text-secondary);
  font-family: var(--font-body);
  font-size: var(--fs-caption);
  font-weight: var(--fw-medium);
  font-variant-numeric: var(--numeric-variant);
}

/* Status dot: solid 8px fill only (kit 6), color pair with its label. */
.ch-dot {
  display: inline-block;
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: var(--radius-full);
  background: currentColor;
}

.ch-dot-success {
  color: var(--success);
}

.ch-dot-warning {
  color: var(--warning);
}

.ch-dot-danger {
  color: var(--danger);
}

.ch-dot-info {
  color: var(--info);
}

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

/* --------------------------------------------------------------------------
   Forms (kit 5.7): themed wrappers around the token layer control styling.
   Every control stays themed in every state, dark fills only.
   -------------------------------------------------------------------------- */

.ch-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.ch-label {
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  font-weight: var(--fw-medium);
  color: var(--text-secondary);
}

.ch-helper {
  font-family: var(--font-body);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--text-muted);
  margin: 0;
}

.ch-error {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--danger);
  margin: 0;
}

.ch-error .ch-icon {
  width: 16px;
  height: 16px;
}

/* The control slot fills the field row width. The border box sizing
   keeps the control's own padding and hairline inside that width at
   every field width, the same containment rule the card CTA slots run. */
.ch-field input,
.ch-field select,
.ch-field textarea,
.ch-select select {
  box-sizing: border-box;
  width: 100%;
}

/* Form stacks (login placeholders and future account surfaces): vertical
   rhythm on the field gap only. */
.ch-form {
  display: grid;
  gap: var(--space-4);
  max-width: 420px;
}

/* Field level invalid state: danger boundary, label stays visible. */
.ch-field .ch-control[aria-invalid="true"],
.ch-field input[aria-invalid="true"],
.ch-field select[aria-invalid="true"],
.ch-field textarea[aria-invalid="true"] {
  border-color: var(--danger);
}

.ch-field-error-list {
  background: var(--surface-sunken);
  border: 1px solid var(--danger);
  border-radius: var(--radius-sm);
  color: var(--danger);
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  padding: var(--space-3) var(--space-4);
  margin: 0 0 var(--space-4);
}

/* Custom drawn checkbox and radio glyphs inside 44px hit boxes (kit 5.7):
   20px glyph, accent fill when checked, border 3 unchecked. */
.ch-check {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 44px;
  min-width: 44px;
  padding: 0 var(--space-2);
  cursor: pointer;
  color: var(--text-secondary);
  font-family: var(--font-body);
  font-size: var(--fs-body-base);
}

.ch-check input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  margin: 0;
}

.ch-glyph {
  position: relative;
  flex: none;
  width: 20px;
  height: 20px;
  border: 1px solid var(--border-3);
  border-radius: var(--radius-xs);
  background: var(--surface-sunken);
  transition: background-color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}

.ch-glyph::after {
  content: "";
  display: none;
  position: absolute;
}

.ch-check:hover .ch-glyph {
  border-color: var(--border-2);
}

.ch-check input:checked + .ch-glyph {
  background: var(--accent);
  border-color: var(--accent);
}

.ch-check input:checked + .ch-glyph::after {
  display: block;
  left: 6px;
  top: 1px;
  width: 5px;
  height: 10px;
  border-inline-end: 2px solid var(--text-on-accent);
  border-block-end: 2px solid var(--text-on-accent);
  transform: rotate(45deg);
}

.ch-check input:focus-visible + .ch-glyph {
  box-shadow: var(--focus-ring);
}

.ch-check input[type="radio"] + .ch-glyph {
  border-radius: var(--radius-full);
}

.ch-check input[type="radio"]:checked + .ch-glyph::after {
  display: block;
  left: 50%;
  top: 50%;
  width: 8px;
  height: 8px;
  border: none;
  border-radius: var(--radius-full);
  background: var(--text-on-accent);
  transform: translate(-50%, -50%);
}

/* Selects: the closed control is fully themed; the native list panel keeps
   the documented OS chrome (kit 5.7 documented scope). The chevron glyph is
   drawn here with two 2px borders in the text token color instead of a
   data URI: a data URI image cannot read token variables, so the pure CSS
   build keeps the glyph on the token set and recolors with the surface. */
.ch-select {
  position: relative;
  display: inline-flex;
  width: 100%;
}

.ch-select select {
  appearance: none;
  width: 100%;
  padding-inline-end: var(--space-9);
}

.ch-select::after {
  content: "";
  position: absolute;
  right: var(--space-4);
  top: 50%;
  width: 8px;
  height: 8px;
  border-inline-end: 2px solid var(--text-secondary);
  border-block-end: 2px solid var(--text-secondary);
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   Dialogs and drawer (kit 5.10): styled overlays only, focus trapped by the
   interface script, scrim tokens for the backdrop, xl shadow, xl radius.
   The native dialog element carries the modal behavior.
   -------------------------------------------------------------------------- */

.ch-dialog {
  position: relative;
  width: 100%;
  max-width: min(560px, calc(100vw - var(--space-8)));
  border: 1px solid var(--border-1);
  border-radius: var(--radius-xl);
  background: var(--bg-modal);
  color: var(--text-primary);
  box-shadow: var(--shadow-xl);
  padding: var(--space-6);
}

.ch-dialog-close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
}

.ch-dialog::backdrop {
  background: var(--scrim-modal);
}

.ch-dialog[open] {
  animation: ch-dialog-in var(--dur-slow) var(--ease-out);
}

@keyframes ch-dialog-in {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* Bottom sheet variant for narrow screens (12px top radius, kit 5.10). */
.ch-dialog-sheet {
  position: fixed;
  inset: auto 0 0 0;
  margin: 0 auto;
  max-width: 100vw;
  border-radius: 12px 12px 0 0;
}

.ch-dialog-title {
  font-family: var(--font-display);
  font-size: var(--fs-title-1);
  line-height: var(--lh-title-1);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  margin: 0;
  padding-inline-end: var(--space-9);
}

.ch-dialog-copy {
  font-family: var(--font-body);
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body);
  color: var(--text-secondary);
  margin: var(--space-3) 0 0;
}

.ch-dialog-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  justify-content: flex-end;
  margin-top: var(--space-6);
}

/* Scrim surfaces: modal scrim behind native dialogs via backdrop; drawer
   scrim is a sibling surface at the drawer layer. */
.ch-scrim {
  background: var(--scrim-modal);
}

.ch-scrim-drawer {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  background: var(--scrim-drawer);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-out);
}

.ch-scrim-drawer[data-open="true"] {
  opacity: 1;
  pointer-events: auto;
}

.ch-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-drawer);
  width: min(320px, 86vw);
  background: var(--bg-raised);
  border-left: 1px solid var(--border-1);
  box-shadow: var(--shadow-xl);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  transform: translateX(100%);
  /* Closed state leaves the tab order and the reader tree as well: the
     hidden visibility lands after the close transition settles. */
  visibility: hidden;
  transition: transform var(--dur-base) var(--ease-out),
    visibility 0s linear var(--dur-base);
}

.ch-drawer[data-open="true"] {
  transform: none;
  visibility: visible;
  transition: transform var(--dur-base) var(--ease-out);
}

.ch-drawer-link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 44px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-family: var(--font-body);
  font-weight: var(--fw-medium);
  font-size: var(--fs-body-base);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out);
}

.ch-drawer-link:hover {
  color: var(--text-primary);
  background: var(--tint-hairline);
}

.ch-drawer-link:focus-visible {
  box-shadow: var(--focus-ring);
  outline: none;
}

.ch-drawer-link[aria-current="page"] {
  color: var(--accent);
  background: var(--accent-tint-2);
}

.ch-drawer-nav {
  display: grid;
  gap: var(--space-1);
  align-content: start;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ch-drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

/* Account entry block of the drawer (phase 4.5): the same identity
   lines and actions as the header, stacked full width while the drawer
   is open. The form block carries the sign out button at full
   hit width. */
.ch-drawer-account {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-1);
}

.ch-drawer-account .ch-account-entry {
  max-width: none;
}

.ch-drawer-account form {
  display: block;
}

/* Visually hidden helper: content stays for readers and reader tools. */
.ch-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border-width: 0;
}

/* Inline icons inherit currentColor by design (kit 6); they size here. */
.ch-icon {
  width: 20px;
  height: 20px;
  flex: none;
}

/* Scroll lock while an overlay is open (toggled by the interface script). */
.ch-lock {
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   Stat band and trust surfaces (kit 5.11): the band is a raised panel with
   the headline, the chip row, and the honest caption line.
   -------------------------------------------------------------------------- */

.ch-stat-band {
  display: grid;
  gap: var(--space-4);
  justify-items: start;
  padding: var(--space-6);
  background: var(--bg-raised);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

.ch-stat-band-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* Column stats for the status surface, one honest value per column. */
.ch-stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.ch-stat-value {
  font-family: var(--font-display);
  font-size: var(--fs-title-1);
  line-height: var(--lh-title-1);
  font-weight: var(--fw-bold);
  color: var(--text-primary);
  font-variant-numeric: var(--numeric-variant);
}

/* --------------------------------------------------------------------------
   Tables (kit 5.6 base layer: surface, striping, tabular numerals)
   -------------------------------------------------------------------------- */

.ch-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border-1);
  border-radius: var(--radius-lg);
  background: var(--surface-card);
}

.ch-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
}

.ch-table th {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-2);
  color: var(--text-muted);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-caption);
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
  text-align: left;
  white-space: nowrap;
}

.ch-table td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-1);
  color: var(--text-secondary);
}

.ch-table tbody tr:nth-child(even) {
  background: var(--tint-hairline);
}

.ch-table td.ch-nums,
.ch-table th.ch-nums {
  text-align: right;
  font-variant-numeric: var(--numeric-variant);
}

/* --------------------------------------------------------------------------
   Hero composition helpers (kit 3.6 and 3.7 glow laws + 4.2 statement hero)
   Two overlapping radial glows (accent strong, ember soft), separately
   placed, behind the copy; text never sits on a blended two hue wash.
   -------------------------------------------------------------------------- */

/* The plain copy-only hero renders as a padded, rounded block (owner
   item 13): the radius sits at the wide band tier of the kit scale and
   clips the glow pair through the overflow rule; the inner padding gives
   the copy breathing room inside the band at every viewport. Split
   heroes carry their photo instead and keep their composition classes. */
.ch-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: var(--radius-xl);
  padding: var(--space-5);
}

@media (min-width: 768px) {
  .ch-hero {
    padding: var(--space-6);
  }
}

.ch-hero::before,
.ch-hero::after {
  content: "";
  position: absolute;
  z-index: -1;
  pointer-events: none;
  inset: 0;
}

.ch-hero::before {
  background: radial-gradient(
    640px 420px at 78% 12%,
    var(--glow-accent-strong),
    transparent 72%
  );
}

.ch-hero::after {
  background: radial-gradient(
    520px 380px at 8% 92%,
    var(--glow-ember-soft),
    transparent 72%
  );
}

.ch-hero-copy {
  display: grid;
  gap: var(--space-5);
  justify-items: start;
  max-width: var(--measure-max);
}

.ch-hero-copy h1,
.ch-hero-copy p {
  margin: 0;
}

.ch-hero-media {
  border-radius: var(--radius-2xl);
  border: 1px solid var(--border-1);
  overflow: hidden;
  background: var(--surface-sunken);
}

/* --------------------------------------------------------------------------
   Glow and bloom utilities (kit 3.6 alpha forms applied through the tokens)
   -------------------------------------------------------------------------- */

.ch-bloom {
  box-shadow: var(--bloom-accent);
}

.ch-wash-accent {
  background: var(--glow-accent-soft);
}

.ch-wash-ember {
  background: var(--glow-ember-soft);
}

.ch-glow-edge-accent {
  box-shadow: 0 0 0 1px var(--glow-accent-strong);
}

.ch-glow-edge-ember {
  box-shadow: 0 0 0 1px var(--glow-ember-strong);
}

/* --------------------------------------------------------------------------
   Footer (kit 5.8: brand column plus four columns maximum, no link farms)
   -------------------------------------------------------------------------- */

.ch-footer {
  background: var(--bg-raised);
  border-top: 1px solid var(--border-1);
  margin-top: var(--space-9);
}

.ch-footer-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  padding-block: var(--space-8);
}

@media (min-width: 768px) {
  .ch-footer-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .ch-footer-grid {
    grid-template-columns: 1.6fr repeat(4, minmax(0, 1fr));
  }
}

.ch-footer-heading {
  font-family: var(--font-body);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
  color: var(--text-muted);
  margin: 0 0 var(--space-2);
}

.ch-footer-links {
  display: grid;
  gap: 0;
  justify-items: start;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ch-footer-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--text-secondary);
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out);
}

/* The hit band of the footer links (TODO line 4.10): the same
   pseudo hit band mechanism the text links ride (ch-link), keeping
   every footer target at or over 44px in both dimensions without any
   layout shift and without any paint. The footer links sit in a gap
   zero list at min height 44px, so the band extends horizontally only:
   a vertical band here would overlap the neighbouring rows' targets,
   and the horizontal reach is the side the measured widths of the
   short labels (Status, Plans, Log in, Terms, DMCA) fall short of. The
   offset tokens are the band's; nothing recolors. */
.ch-footer-link::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--space-2) * -1);
  right: calc(var(--space-2) * -1);
  border-radius: var(--radius-xs);
}

.ch-footer-link:hover {
  color: var(--text-primary);
}

.ch-footer-link:focus-visible {
  box-shadow: var(--focus-ring);
  outline: none;
  border-radius: var(--radius-xs);
}

.ch-footer-legal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: var(--space-5);
  border-top: 1px solid var(--border-1);
  color: var(--text-muted);
  font-family: var(--font-body);
  font-size: var(--fs-caption);
}

.ch-footer-brand {
  display: grid;
  gap: var(--space-3);
  align-content: start;
  justify-items: start;
}

.ch-footer-brand img {
  height: auto;
  max-height: 96px;
  width: auto;
  display: block;
}

/* --------------------------------------------------------------------------
   Misc structural helpers
   -------------------------------------------------------------------------- */

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

.ch-chip-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.ch-heading-row {
  display: grid;
  gap: var(--space-2);
  margin-bottom: var(--space-6);
  /* The document width law (owner fix pass): a display heading inside
     the row carries its own longest word at display font size; an
     account or guide name token longer than the viewport line may set
     break opportunities anywhere so the row can never push the
     document body wider than the viewport. Prose rhythm and the grid
     gap stay untouched. */
  overflow-wrap: anywhere;
}
/* --------------------------------------------------------------------------
   Kit completion pass: pricing grid and card anatomy (kit 5.5), comparison
   table behaviors (kit 5.6), status dot row, table glyphs, hero split with
   the scrim edge, empty states, the inert reveal class, and the reduced
   motion collapses for the overlays.
   -------------------------------------------------------------------------- */

/* Pricing grid: one column mobile, two tablet, three desktop, four wide.
   Cards keep equal height without scaling on emphasis (kit 5.5 rule).
   The row carding contract: grid auto rows size to the tallest padded
   card of each row at every breakpoint (the 16px mobile row gap and the
   24px tablet gap are the layout of record), and no card may paint over
   the row above; nothing on a card carries a horizontal or vertical
   percentage height that would shrink the row track sizing. */
.ch-plan-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

@media (min-width: 768px) {
  .ch-plan-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-6);
  }
}

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

@media (min-width: 1280px) {
  .ch-plan-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Pricing card zones, top to bottom (kit 5.5). Zones render only with
   content; the chip row hides when the family chip slot stays empty.
   No height rule sits on the card: the grid stretches every item to its
   row, and a cyclic percentage height shrank the auto row track sizing
   below the card's padded box, which made card rows paint over each
   other and every following block sit on the last row. Rows keep the
   equal height look through the grid's own stretch, never through a
   height of record on the card. */
.ch-plan-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.ch-plan-chip-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  min-height: 0;
}

.ch-plan-chip-row:empty {
  display: none;
}

.ch-plan-name {
  font-family: var(--font-display);
  font-size: var(--fs-title-2);
  line-height: var(--lh-title-2);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  margin: 0;
}

/* The headline resource numeral: display face, big, with the unit label
   riding smaller beside it. */
.ch-plan-resource {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-family: var(--font-display);
  font-size: var(--fs-display-3);
  line-height: var(--lh-display-3);
  font-weight: var(--fw-bold);
  color: var(--text-primary);
  font-variant-numeric: var(--numeric-variant);
}

.ch-plan-unit {
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  font-weight: var(--fw-medium);
  color: var(--text-secondary);
}

.ch-plan-guidance {
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  color: var(--text-secondary);
  margin: 0;
}

/* Price block: display numerals with the cycle unit beneath (kit 4.3).
   Tabular figures align cycle columns; the calling view owns values. */
.ch-plan-price {
  display: grid;
  gap: var(--space-1);
  justify-items: start;
  font-family: var(--font-display);
  font-size: var(--fs-display-4);
  line-height: var(--lh-display-4);
  font-weight: var(--fw-bold);
  color: var(--text-primary);
  font-variant-numeric: var(--numeric-variant);
}

.ch-plan-cycle {
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  font-weight: var(--fw-regular);
  color: var(--text-secondary);
}

/* Feature tick list: sixteen px leading plus label with the check mark
   glyph leading every row (kit 5.5 zone list). */
.ch-plan-features {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-2);
  justify-items: start;
}

.ch-plan-features li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--fs-body-base);
  line-height: var(--lh-body);
  color: var(--text-secondary);
}

.ch-plan-features .ch-glyph-check {
  color: var(--success);
}

/* Call to action zone: full width button pinned to the card floor. */
.ch-plan-cta {
  margin-top: auto;
}

.ch-plan-cta .ch-btn,
.ch-plan-cta .ch-btn-block {
  width: 100%;
}

/* Under row note: the plain cycles note in caption muted. */
.ch-plan-note {
  font-family: var(--font-body);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--text-muted);
  margin: 0;
}

/* --------------------------------------------------------------------------
   Shared plan set and cycle switch (plans page composition): the base set
   identical across all seven tiers renders once in its own card above the
   grid, and one cycle switch row carries the page level cycle state instead
   of a chip row per card. Both stay server rendered on every cycle variant.
   -------------------------------------------------------------------------- */

.ch-included-card {
  display: grid;
  gap: var(--space-3);
  align-content: start;
  justify-items: start;
}

.ch-included-list {
  width: 100%;
  grid-template-columns: 1fr;
  column-gap: var(--space-6);
}

@media (min-width: 768px) {
  .ch-included-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .ch-included-list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.ch-cycle-switch {
  display: grid;
  gap: var(--space-3);
  justify-items: start;
}

.ch-cycle-switch .ch-chip-row {
  flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   Comparison table behaviors (kit 5.6): sticky first column, edge fade on
   narrow screens, and the hit rule for interactive cell controls.
   -------------------------------------------------------------------------- */

.ch-compare-wrap {
  position: relative;
  min-width: 0;
}

/* Right edge fade while the table can scroll on narrow screens; the fade
   lifts above the rows without blocking them. */
.ch-table-fade {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 56px;
  background: linear-gradient(to right, transparent, var(--surface-card));
  opacity: 0;
  pointer-events: none;
  z-index: 2;
}

@media (max-width: 767px) {
  .ch-table-fade {
    opacity: 1;
  }
}

.ch-compare-table th:first-child,
.ch-compare-table td:first-child,
.ch-compare-table tbody th:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--surface-card);
  box-shadow: inset -1px 0 0 var(--border-1);
}

/* Row scope cells read at the primary tier. */
.ch-table tbody th {
  text-align: left;
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
}

/* Comparison table alignment of record (plans page): the whole table
   reads one alignment, centered, because mixed row and numeric
   alignments read as chaos side by side. Header cells, row labels, and
   every data cell center; the tabular numerals rule stays (the nums
   font variant is untouched, only the horizontal alignment changes).
   The modifier scopes the centering to the comparison table instance
   that opts in through the wrapper class, so other kit tables keep
   their own alignment; two arms carry the whole rule: every cell level
   (:is(th, td) beats the base left and right rules in source order),
   and the nums cells that the blanket kit rule would re right align. */
.ch-compare-center .ch-compare-table :is(th, td),
.ch-compare-center .ch-compare-table :is(td, th).ch-nums {
  text-align: center;
}

/* Interactive controls inside cells carry the hit rule: the visual box may
   stay compact above the enlarged hit height. */
.ch-compare-table :is(td, th) :is(a, button) {
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
}

/* Check and minus glyph marks (kit 5.6): success check, and the neutral
   tint pill carrying the minus with its own label in markup. */
.ch-glyph-check {
  display: inline-flex;
  align-items: center;
  color: var(--success);
}

.ch-glyph-check .ch-icon {
  width: 20px;
  height: 20px;
}

.ch-glyph-minus {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  min-width: 24px;
  height: 24px;
  border-radius: var(--radius-full);
  background: var(--tint-2);
  color: var(--text-muted);
}

.ch-glyph-minus .ch-icon {
  width: 14px;
  height: 14px;
}

/* --------------------------------------------------------------------------
   Status dot row (kit 5.9 and 5.11): dot plus text label, color never the
   only signal.
   -------------------------------------------------------------------------- */

.ch-status-dot {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  color: var(--text-secondary);
}

/* Uppercase chip option (kit 5.9): micro tracking on a caption pill. */
.ch-chip-upper {
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
}

/* --------------------------------------------------------------------------
   Hero split composition: copy on the canvas, the rack photo beside it
   with the dark scrim edge (kit 7). Exactly one visual moment per hero:
   the photo treatment here, the glow pair only on surfaces without a
   photo. Text never sits on a blended two hue wash.
   -------------------------------------------------------------------------- */

.ch-hero-split {
  display: grid;
  align-items: center;
  gap: var(--space-6);
}

@media (min-width: 768px) {
  .ch-hero-split {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (min-width: 1024px) {
  .ch-hero-split {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: var(--space-10);
  }
}

.ch-hero-media {
  position: relative;
  margin: 0;
  aspect-ratio: 3 / 2;
}

.ch-hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* The dark scrim edge: the modal scrim token washing up from the lower
   edge so the photo lands into the graphite canvas. */
.ch-hero-media-scrim::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, var(--scrim-modal) 0%, transparent 45%);
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   Empty states and account placeholder cards: a small card pattern for
   surfaces that publish later, stated plainly without invented content.
   -------------------------------------------------------------------------- */

.ch-empty {
  display: grid;
  gap: var(--space-4);
  justify-items: start;
  padding: var(--space-8) var(--space-6);
}

.ch-empty .ch-heading-row,
.ch-empty p,
.ch-empty h1,
.ch-empty h2 {
  margin: 0;
}

.ch-empty-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-2);
}

.ch-card-narrow {
  max-width: 440px;
}

/* Contact page compact composition (owner item 19): the form area and
   the two channel cards share one section with no dead seam between
   them. The form column holds the prose measure of record; the channels
   stack beside it from the wide breakpoint, and narrower screens keep
   the single column order with tight gaps inside the section rhythm. */
.ch-contact-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

.ch-contact-channels {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  align-content: start;
}

@media (min-width: 1024px) {
  .ch-contact-grid {
    grid-template-columns: minmax(0, var(--measure-max)) minmax(0, 1fr);
    align-items: start;
    gap: var(--space-6);
  }
}

/* --------------------------------------------------------------------------
   Inert scroll reveal class (kit 8): shipped for the future pass with NO
   scripting in the current kit step. The class stays unused today: no
   script sets the revealed flag, so nothing on the pages animates on
   scroll. Never apply it to pricing, legal, or form content.
   -------------------------------------------------------------------------- */

.ch-reveal {
  opacity: 0;
  transform: translateY(12px);
}

.ch-reveal[data-ch-revealed="true"] {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out);
}

/* --------------------------------------------------------------------------
   Overlay close affordances (kit 5.10): the dialog close button sits at
   the top corner and keeps the full hit size.
   -------------------------------------------------------------------------- */

.ch-dialog .ch-dialog-close {
  position: absolute;
}

/* --------------------------------------------------------------------------
   Reduced motion collapses for the overlays: the tokens file already
   collapses every transition globally; these explicit rules keep the
   drawer and dialog states readable without motion entirely.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .ch-drawer,
  .ch-scrim-drawer {
    transition: none;
  }

  .ch-dialog[open] {
    animation: none;
  }

  .ch-card:hover,
  .ch-card:focus-visible {
    transform: none;
  }

  .ch-btn:active {
    transform: none;
  }
}

/* --------------------------------------------------------------------------
   Visibility helper: hidden elements leave the layout entirely, so the
   dismissed banner and the closed drawer scrim drop out at once.
   -------------------------------------------------------------------------- */

[hidden] {
  display: none !important;
}

/* Offset utility for demo rows standing apart from a preceding block. */
.ch-offset-block {
  margin-top: var(--space-6);
}

/* --------------------------------------------------------------------------
   Kit completion pass: long form article body and the card actions zone
   (the knowledge base article template and index rows of record). One
   block flow class on token pairs; tables reuse the kit table anatomy
   above; every control the article renders is a kit component.
   -------------------------------------------------------------------------- */

.ch-article {
  display: grid;
  gap: var(--space-5);
  align-content: start;
  /* The document width law (owner fix pass): long unbreakable tokens in
     guide and legal prose may set break opportunities anywhere at the
     flow level, so a single long word can never push the document wider
     than the viewport. Table cells opt back out below: wide tables keep
     readable column widths and scroll inside their contained wrapper
     instead of breaking their words. */
  overflow-wrap: anywhere;
}

/* The article title row: the topic badge sits beside the H1 on wide
   viewports and wraps below it on narrow ones; the wrapped case gets
   this row gap against the title block (above the 12px floor of record). */
.ch-article .ch-row {
  row-gap: var(--space-4);
}

.ch-article ul,
.ch-article ol {
  margin: 0;
  padding-left: var(--space-6);
}

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

.ch-article code {
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  color: var(--text-primary);
  background: var(--surface-sunken);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-2);
}

/* The card component's actions zone (kit 5.5 anatomy) renders the actions
   slot today with no spacing rule of its own; this completes the zone. */
.ch-card-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

/* --------------------------------------------------------------------------
   Money back body zone (4.9): the block flow for the guarantee card
   paragraphs and the refund policy page paragraphs of record. The same
   token gap the article flow uses; the wording itself lives in the site
   lang file of record and never in styles or templates.
   -------------------------------------------------------------------------- */

.ch-money-back-body {
  display: grid;
  gap: var(--space-5);
  align-content: start;
}

/* --------------------------------------------------------------------------
   Legal article tables and emphasis (4.11): the published legal pages
   render GFM tables (the privacy retention table of record) and bold
   runs inside the article flow. The rules reuse the kit table anatomy
   and token pairs so nothing on the dark scope renders as unstyled
   default chrome; header and cell text wrap, no whitespace nowrap.
   -------------------------------------------------------------------------- */

.ch-article table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  background: var(--surface-card);
  border: 1px solid var(--border-1);
  /* Tables opt out of the article flow's anywhere wrapping: cell words
     hold their readable widths and the table itself always lives inside
     a contained horizontal scroll wrapper (the kit wrapper on the kit
     tables, the pipeline wrapper around the published legal tables). */
  overflow-wrap: normal;
}

.ch-article table th {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-2);
  color: var(--text-muted);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-caption);
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
  text-align: left;
}

.ch-article table td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-1);
  color: var(--text-secondary);
}

.ch-article table tr:last-child > * {
  border-bottom: 0;
}

.ch-article strong {
  color: var(--text-primary);
  font-weight: var(--fw-semibold);
}

/* Legal article block rhythm (owner item 21, fix pass 2026-10-16): the
   published legal pages inject raw GFM markdown, so their blocks are
   unclassed elements whose default browser margins stack on the grid
   gap (a paragraph pair sat at margin 16 plus gap 20 plus margin 16 =
   52px of air). The modifier zeroes those margins inside the legal
   article and tightens the block rhythm to the 16 to 32px law with the
   clean 16px mobile and 20px desktop pair: the grid gap is the only
   vertical rhythm between blocks, list rows keep their 8px step, and
   every inter block edge lands inside the law at every viewport.
   Scoped to the legal view only: the knowledge base article blocks
   carry their own class driven fixed rhythm, the refund policy body
   reads on the classed body tiers, and neither carries raw markdown,
   so neither needs this scope and both stay unshifted (their block
   edges stay far under the 32px cap as shipped). Nothing here touches
   the padding inside an interactive control; the 44px hit floors of
   the kit stand untouched. */
.ch-article-legal {
  gap: var(--space-4);
}

@media (min-width: 768px) {
  .ch-article-legal {
    gap: var(--space-5);
  }
}

.ch-article-legal :is(h1, h2, h3, h4, h5, h6, p, ul, ol, table, blockquote, pre, hr) {
  margin: 0;
}

/* --------------------------------------------------------------------------
   Account area (phase 4.4, line B): the auth divider under the sign in
   and register forms, the profile lines, the suspension banner, and the
   add form structure. Colors and sizes come from the tokens only.
   -------------------------------------------------------------------------- */

.ch-auth-divider {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-5) 0;
  color: var(--text-muted);
  font-family: var(--font-body);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
}

.ch-auth-divider::before,
.ch-auth-divider::after {
  content: '';
  display: block;
  flex: 1;
  border-top: 1px solid var(--border-1);
}

.ch-account-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-lg);
  background: var(--tint-2);
}

.ch-account-banner p {
  margin: 0;
  color: var(--text-secondary);
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
}

.ch-account-profile {
  display: grid;
  gap: 0;
  margin: 0;
}

.ch-account-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--border-1);
}

.ch-account-line:last-child {
  border-bottom: 0;
}

.ch-account-line dt {
  flex-shrink: 0;
  color: var(--text-secondary);
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-semibold);
}

.ch-account-line dd {
  margin: 0;
  text-align: right;
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--fs-body-base);
  line-height: 1.5;
  overflow-wrap: break-word;
}

.ch-account-missing {
  color: var(--text-muted);
}

.ch-account-form {
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-1);
}

.ch-account-form + .ch-account-form {
  margin-top: var(--space-6);
}

.ch-account-subhead {
  margin: 0 0 var(--space-2);
  font-family: var(--font-display);
  font-size: var(--fs-title-2);
  font-weight: var(--fw-semibold);
}

.ch-account-intro {
  margin: 0;
  color: var(--text-secondary);
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
}

/* --------------------------------------------------------------------------
   Client area additions (phase 4.6, brand kit 9.4): the join address
   affordance of the server item card. The address sits in mono on the
   sunken surface behind a hairline, with the 44 px square copy button
   beside it; the copy runs through the interface script only (no native
   dialogs). Dark tokens only, as everywhere in the kit.
   -------------------------------------------------------------------------- */

.ch-join {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--surface-sunken);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
}

.ch-join-address {
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  color: var(--text-secondary);
  font-variant-numeric: var(--numeric-variant);
  overflow-wrap: anywhere;
  margin: 0;
}

/* --------------------------------------------------------------------------
   Form abuse gate additions (phase Q line): the honeypot class zeroes the
   footprint of the trap field, the hidden badge variant keeps the widget
   chrome invisible while the required attribution line stays visible, and
   the note carries that sentence beside every protected form submit. The
   classes are inert wherever no protected form renders: nothing styles a
   form control here, and no light surface appears.
   ------------------------------------------------------------------------- */

/* The honeypot trap class: one pixel box, zero paint, out of the flow,
   never on any focus path (the markup adds tabindex -1 and the hidden
   state to the assistive tree as well). */
.ch-hp {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  opacity: 0;
  visibility: hidden;
}

/* The hidden badge variant of record: the widget's floating badge stays
   out of view while the token still verifies (the documented variant),
   and the required attribution line beside the submit remains visible. */
.grecaptcha-badge {
  visibility: hidden;
}

/* The attribution note: the caption law text with the two kit links, set
   below the submit at the section's own spacing. */
.ch-recaptcha-note {
  margin: var(--space-3) 0 0;
}
