/* WTC Design System v0.1 — components.
   Contracts, variants and states: ../COMPONENTS.md */

/* ---- Brand mark ------------------------------------------------------ */
/* The "?!" device used inside band patterns, headings and stamps. The old
   boxed header wordmark was removed with the sticky header itself
   (internal ref): the brand now speaks through the printed layers. */
.wtc-wordmark__mark { color: var(--wtc-text-accent); -webkit-text-stroke: 0.5px var(--wtc-border-strong); }

/* ---- Site header ----------------------------------------------------- */
/* internal ref: quiet orientation restored after the -006 over-removal.
   Sticky so the brand link back to #top stays reliable after scrolling —
   but stationery-quiet: one slim veiled-paper bar, textual wordmark, one
   subordinate Anfrage link. No boxed wordmark, no CTA field. The veil token
   exists for exactly this surface (see tokens.css). */
.wtc-header {
  position: sticky;
  top: 0;
  z-index: 20; /* above the strike stamp (z 6) while scrolling */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--wtc-space-4);
  min-height: 48px;
  padding: 0 var(--wtc-gutter);
  background: var(--wtc-surface-page-veil);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border-bottom: var(--wtc-border-width-hair) solid var(--wtc-border-hairline);
}
.wtc-header__brand {
  display: inline-flex;
  align-items: center;
  min-height: var(--wtc-hit-min);
  font-family: var(--wtc-font-display);
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: var(--wtc-tracking-display);
  text-decoration: none;
  /* The wordmark and its reaction mark are one object: never let them wrap
     onto separate lines at compact widths (320/390/430). */
  white-space: nowrap;
}
.wtc-header__brand:hover { color: var(--wtc-text-primary); text-decoration: underline; text-underline-offset: 0.3em; }
/* Reaction mark (internal ref). Previously the mark merely inherited the
   wordmark's ink with no spacing at all — measured flush against "CAKE" at
   every width — so it read as ordinary trailing punctuation instead of the
   brand's reaction device.
   It is now a compact printed stamp, using this system's existing stamp
   grammar (accent field + ink rule + --wtc-stamp-rotate-mark), detached by
   four independent devices so the separation never depends on colour alone:
   explicit spacing, its own bordered field, rotation, and being its own
   inline-block box. Legible as a separate object even in greyscale.
   Contrast: the old rule forced ink BECAUSE magenta text on paper is 3.48:1
   and fails AA at 1rem. Inverting the pairing fixes that — ink on the accent
   field is 4.55:1 and passes, the same pairing .wtc-reveal and the checked
   .wtc-choice__text already ship. The link's own wordmark text is untouched.
   Header-scoped on purpose: the band, CTA-card, heading and aftershock marks
   keep their own treatments and must not move with this. */
.wtc-header__brand .wtc-wordmark__mark {
  display: inline-block;
  margin-inline-start: 0.45em;
  padding: 0.06em 0.26em;
  background: var(--wtc-surface-accent);
  color: var(--wtc-text-primary);
  border: var(--wtc-border-width-rule) solid var(--wtc-border-strong);
  -webkit-text-stroke: 0;
  transform: rotate(var(--wtc-stamp-rotate-mark));
  /* The stamp is a brand device, not a link affordance: keep the hover
     underline on the wordmark text only. */
  text-decoration: none;
}
.wtc-header__cta {
  display: inline-flex;
  align-items: center;
  min-height: var(--wtc-hit-min);
  font-family: var(--wtc-font-label);
  font-size: var(--wtc-type-label-lg);
  letter-spacing: var(--wtc-tracking-label);
  text-transform: uppercase;
}

/* ---- Buttons -------------------------------------------------------- */
.wtc-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--wtc-space-2);
  min-height: var(--wtc-hit-primary);
  padding-inline: var(--wtc-space-6);
  border: none;
  border-radius: var(--wtc-radius);
  background: var(--wtc-surface-inverse);
  color: var(--wtc-text-inverse);
  font-family: var(--wtc-font-display);
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--wtc-elevation-print);
  transition: transform var(--wtc-duration-ui) var(--wtc-ease-ui),
              box-shadow var(--wtc-duration-ui) var(--wtc-ease-ui);
}
.wtc-btn:hover { color: var(--wtc-text-inverse); transform: translate(-1px, -1px); box-shadow: var(--wtc-elevation-print-hover); }
.wtc-btn:active { transform: translate(2px, 2px); box-shadow: var(--wtc-elevation-print-active); }

/* On an inverse surface the print shadow needs a light offset to stay visible. */
.wtc-surface--inverse .wtc-btn--on-paper {
  background: var(--wtc-surface-inverse);
  color: var(--wtc-text-inverse);
}

.wtc-btn-quiet {
  display: inline-flex;
  align-items: center;
  min-height: var(--wtc-hit-min);
  padding-inline: var(--wtc-space-2);
  background: none;
  border: none;
  font: inherit;
  font-size: var(--wtc-type-body-small);
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.35em;
  cursor: pointer;
}

/* ---- Cake frame + reveal control ------------------------------------ */
.wtc-frame {
  position: relative;
  aspect-ratio: var(--wtc-aspect-cake);
  background: var(--wtc-surface-inverse);
  overflow: hidden;
  box-shadow: var(--wtc-elevation-frame);
}
/* --wtc-frame-focus lets each slide nudge its crop's vertical anchor per-image
   (set inline per .wtc-frame instance) without a bespoke rule per slide. */
.wtc-frame__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center var(--wtc-frame-focus, 50%); }

.wtc-frame__band {
  position: absolute;
  left: 0;
  right: 0;
  background: var(--wtc-surface-page);
  overflow: hidden;
}
/* Two printed flaps fold over the cake, leaving a die-cut peek window
   (the ~16% gap between them) where a real, unenhanced slice of the photo
   shows through — enough to invite curiosity, not enough to recognise the
   cake. This is the concealment itself, not decoration around it. */
.wtc-frame__band--top { top: 0; height: 42%; border-bottom: var(--wtc-border-width-print) dashed var(--wtc-border-strong); }
.wtc-frame__band--bottom { bottom: 0; height: 42%; border-top: var(--wtc-border-width-print) dashed var(--wtc-border-strong); }
.wtc-frame__pattern {
  position: absolute;
  inset: -70% -20%;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  align-content: center;
  transform: rotate(-6deg);
  font-family: var(--wtc-font-display);
  font-size: 1.25rem;
  text-transform: uppercase;
  opacity: 0.85;
}
.wtc-frame__pattern .wtc-wordmark__mark { -webkit-text-stroke: 0; }

/* Peek layer — sits only in the ~16% die-cut gap between the two bands, over
   the real photo. Milky/translucent parchment, not a disabled-looking flat
   tint: a vertical gradient (denser at the edges, lighter at the centre) plus
   a soft inset shadow on both edges reads as a physical paper/vellum layer
   with depth, and the light backdrop-filter blur only ever touches this
   layer's own compositing — the underlying <img> pixels are never filtered.
   Purely decorative tease: aria-hidden, pointer-events none, JS-only (without
   JS there is no framing at all, so nothing here to half-render). */
.wtc-frame__peek {
  position: absolute;
  left: 0;
  right: 0;
  top: 42%;
  height: 16%;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    var(--wtc-surface-peek-edge) 0%,
    var(--wtc-surface-peek-core) 42%,
    var(--wtc-surface-peek-core) 58%,
    var(--wtc-surface-peek-edge) 100%
  );
  -webkit-backdrop-filter: blur(1.5px);
  backdrop-filter: blur(1.5px);
  box-shadow:
    inset 0 3px 5px rgba(23, 19, 16, 0.10),
    inset 0 -3px 5px rgba(23, 19, 16, 0.10);
}
.wtc-frame[data-phase="revealed"] .wtc-frame__peek { display: none; }

.wtc-reveal {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: inline-flex;
  align-items: center;
  gap: var(--wtc-space-2);
  min-height: var(--wtc-hit-min);
  padding-inline: var(--wtc-space-4);
  z-index: 5;
  background: var(--wtc-surface-accent);
  color: var(--wtc-text-primary);
  border: var(--wtc-border-width-print) solid var(--wtc-border-strong);
  font-family: var(--wtc-font-label);
  font-size: var(--wtc-type-label-lg);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  text-align: start;
}
.wtc-reveal:hover { background: var(--wtc-surface-inverse); color: var(--wtc-surface-accent); }
.wtc-reveal:focus-visible { outline-color: var(--wtc-border-strong); outline-offset: 3px; }
/* Micro-animation opening cue — a chevron that nudges forward on hover/focus.
   Uses the same --wtc-duration-ui token as the rest of the UI layer, so it
   collapses to 1ms under reduced/off motion automatically, no extra rule. */
.wtc-reveal__icon { display: inline-flex; transition: transform var(--wtc-duration-ui) var(--wtc-ease-ui); }
.wtc-reveal:hover .wtc-reveal__icon,
.wtc-reveal:focus-visible .wtc-reveal__icon { transform: translateX(3px); }

/* Impact stamp — the animated payoff. The cake is not the trick; this is.
   The ONLY place yellow appears in the product surface.
   internal ref: the stamp is no longer a centered in-frame banner. It
   lives in the SLIDE (a sibling after `.wtc-frame`, which is
   `overflow: hidden` and would clip it) and strikes diagonally ACROSS the
   frame's upper edge: its vertical center is anchored on the frame's top
   boundary (`top: var(--wtc-slide-pad)` = the frame's offset inside the
   padded slide, + `translateY(-50%)`), with a stronger rotation
   (`--wtc-stamp-rotate-strike`). Roughly half the stamp lands above the
   photo — completing the `Und alle so:` line directly above it — and only
   the lower half overlaps the image's top edge, so the cake itself stays
   visible. `--wtc-slide-pad` (on `.wtc-slide`) reserves exactly the
   overhang room above the frame, so the slider viewport's `overflow:
   hidden` never clips the strike. */
.wtc-aftershock {
  --wtc-aftershock-inset: 2%;
  position: absolute;
  left: var(--wtc-aftershock-inset);
  right: var(--wtc-aftershock-inset);
  top: var(--wtc-slide-pad);
  background: var(--wtc-surface-aftershock);
  color: var(--wtc-text-primary);
  font-family: var(--wtc-font-display);
  font-size: var(--wtc-strike-size);
  line-height: 1.05;
  text-align: center;
  text-transform: uppercase;
  padding: 0.4em 0.5em;
  border: var(--wtc-border-width-print) solid var(--wtc-border-strong);
  box-shadow: var(--wtc-elevation-print);
  transform: translateY(-50%) rotate(var(--wtc-stamp-rotate-strike));
  z-index: 6;
}
/* Magenta-on-yellow fails AA (2.69:1 at large text); keep the mark ink here,
   matching this system's existing yellow-background contrast discipline. */
.wtc-aftershock .wtc-wordmark__mark { color: inherit; -webkit-text-stroke: 0; }

/* Motion grammar: anticipation -> rupture -> impact. The cake photo itself is
   never the animated trick — only the printed layers move. */
@keyframes wtc-band-out-top { to { transform: translateY(-120%) rotate(-6deg); opacity: 0; } }
@keyframes wtc-band-out-bottom { to { transform: translateY(120%) rotate(6deg); opacity: 0; } }
/* Every step re-states translateY(-50%): the animation targets `transform`
   directly, so any step that omitted it would overwrite the static rule's
   vertical centering above (including at the held "to" state — this is what
   reduced/no motion resolve to, per --wtc-duration-aftershock: 1ms). */
@keyframes wtc-stamp-land {
  from { opacity: 0; transform: translateY(-50%) scale(1.6) rotate(4deg); }
  65% { opacity: 1; transform: translateY(-50%) scale(0.97) rotate(calc(var(--wtc-stamp-rotate-strike) + 2deg)); }
  to { opacity: 1; transform: translateY(-50%) scale(1) rotate(var(--wtc-stamp-rotate-strike)); }
}

.wtc-frame[data-phase="rupture"] .wtc-frame__band--top { animation: wtc-band-out-top var(--wtc-duration-rupture) var(--wtc-ease-rupture) both; }
.wtc-frame[data-phase="rupture"] .wtc-frame__band--bottom { animation: wtc-band-out-bottom var(--wtc-duration-rupture) var(--wtc-ease-rupture) both; }
/* Sibling combinator, not descendant: the stamp sits beside the frame in the
   slide so it can cross the frame's clipped upper edge. */
.wtc-frame[data-phase="revealed"] + .wtc-aftershock { animation: wtc-stamp-land var(--wtc-duration-aftershock) var(--wtc-ease-aftershock) var(--wtc-delay-aftershock) both; }

/* Stage variant (internal ref). On the stage the stamp is not the
   conclusion of a rupture — there is nothing to react to, because the
   flagship was never concealed — so it is printed matter that is simply
   there at first paint. Two concrete reasons beyond the aesthetic one:
   the land keyframe overshoots to scale(1.6), and the slide's clip edge
   (.wtc-slider__viewport's overflow:hidden) is what absorbs that overshoot
   inside the gallery — the stage has no such container, so an animated
   overshoot would push the document's scrollWidth past the viewport at
   compact widths; and an entry point should be complete at first paint
   rather than have its payoff arrive 480ms late. Equal specificity to the
   rule above, placed after it, so source order decides. */
.wtc-frame[data-phase="revealed"] + .wtc-aftershock--stage { animation: none; }

/* ---- Product Reveal Slider ------------------------------------------- */
/* Slider state (which product is showing) is fully separate from each
   slide's own reveal state (its .wtc-frame's data-phase, untouched by
   navigation). Track position is driven by --wtc-slide-index, a plain CSS
   custom property set on the track by JS — percentage-based translateX is
   relative to the track's own box, so this stays correct across resize with
   no JS recalculation. Without JS the property is never set, so `0` (the
   var() fallback) always wins and slide 1 (Capybara) is the only one in
   view — the required no-JS baseline, with no extra markup or logic. */
.wtc-slider { position: relative; }
/* padding + equal negative margin: gives the active frame's ambient
   box-shadow room to bleed vertically without being clipped by the
   overflow:hidden this needs horizontally (to hide the inactive slide),
   while leaving the viewport's own occupied layout height unchanged. */
.wtc-slider__viewport { overflow: hidden; padding-block: 18px; margin-block: -18px; }
.wtc-slider__track {
  display: flex;
  transform: translateX(calc(-100% * var(--wtc-slide-index, 0)));
  transition: transform var(--wtc-duration-slide) var(--wtc-ease-ui);
}
/* --wtc-slide-pad reserves the strike stamp's overhang room above the frame
   (half the stamp's height plus its rotation lift): the stamp's center rides
   the frame's top edge, so everything above that edge must fit inside the
   slide's own box or the slider viewport's overflow:hidden would clip it. */
.wtc-slide {
  flex: 0 0 100%;
  min-width: 0;
  position: relative;
  padding-top: var(--wtc-slide-pad);
}

.wtc-slider__nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--wtc-space-3);
  margin-top: var(--wtc-space-4);
}
.wtc-slider__arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--wtc-hit-min);
  height: var(--wtc-hit-min);
  padding: 0;
  background: var(--wtc-surface-page);
  color: var(--wtc-text-primary);
  border: var(--wtc-border-width-print) solid var(--wtc-border-strong);
  cursor: pointer;
  box-shadow: var(--wtc-elevation-print);
  transition: transform var(--wtc-duration-ui) var(--wtc-ease-ui), box-shadow var(--wtc-duration-ui) var(--wtc-ease-ui), opacity var(--wtc-duration-ui) var(--wtc-ease-ui);
}
.wtc-slider__arrow:hover:not(:disabled) { transform: translate(-1px, -1px); box-shadow: var(--wtc-elevation-print-hover); }
.wtc-slider__arrow:active:not(:disabled) { transform: translate(2px, 2px); box-shadow: var(--wtc-elevation-print-active); }
.wtc-slider__arrow:disabled { opacity: 0.35; cursor: not-allowed; box-shadow: none; }

/* Register: quiet print-square dots instead of full-width labeled tabs —
   labeled tabs do not scale to eight slides at 390px, and the founder feedback
   (internal ref) explicitly demoted the register from a second control
   system to quiet progress. Each dot is a 32×44 hit area around a small
   square glyph; the product name lives in the aria-label. */
.wtc-slider__register { display: flex; }
.wtc-slider__dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: var(--wtc-hit-min);
  padding: 0;
  background: transparent;
  border: none;
  cursor: pointer;
}
.wtc-slider__dot::before {
  content: "";
  width: 10px;
  height: 10px;
  border: var(--wtc-border-width-rule) solid var(--wtc-border-strong);
  background: transparent;
  transition: background var(--wtc-duration-ui) var(--wtc-ease-ui);
}
.wtc-slider__dot[aria-selected="true"]::before {
  background: var(--wtc-surface-accent);
  border-width: var(--wtc-border-width-print);
  width: 12px;
  height: 12px;
}
.wtc-slider__dot:disabled { cursor: not-allowed; opacity: 0.5; }

/* Narrow-width register swap (internal ref, absorbing internal ref).
   The dot register's width is inventory-driven and cannot shrink: eight dots
   need 8 × 32px = 256px, plus two 44px arrows and two 12px gaps, so the nav
   demands exactly 368px. The page gutter is clamp(1.25rem, 4vw, 3.5rem),
   which resolves to 20px on every viewport up to 500px, so the content box
   is `100vw - 40px` there. 368 + 40 = 408: below 408px the dot register
   physically cannot fit, and it is that measured fit — not a device name —
   that sets the breakpoint below.

   Below 408px the register is replaced by a compact current/total counter
   rather than being shrunk, clipped or scrolled: shrinking eight dots would
   push their hit areas below a reliable size, and the register was already
   demoted to quiet progress (internal ref), so a literal "7/8" states
   the same progress more legibly than eight 3mm squares. Both arrows keep
   their full 44px targets at every width, and the counter carries a
   visually-hidden accessible name in the same "<name>, N von 8" form the
   dots use, so position and inventory stay perceivable non-visually.
   Exactly one of the two is ever in the DOM's accessibility tree. */
.wtc-slider__count {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: var(--wtc-hit-min);
  height: var(--wtc-hit-min);
  margin: 0;
  font-family: var(--wtc-font-label);
  font-size: var(--wtc-type-label-lg);
  letter-spacing: var(--wtc-tracking-label);
  font-variant-numeric: tabular-nums;
  color: var(--wtc-text-primary);
}
.wtc-slider__count-visual { white-space: nowrap; }

/* The two queries are exact complements of each other on purpose. A
   `max-width: 407.98px` counterpart would leave a hairline band (a layout
   viewport of exactly 407.99px, reachable via zoom on some engines) in which
   NEITHER rule applies and BOTH controls render — which is precisely the
   overflow this repair exists to remove. `not all and (min-width: 408px)` has
   no such gap. */
@media (min-width: 408px) {
  .wtc-slider__count { display: none; }
}
@media not all and (min-width: 408px) {
  .wtc-slider__register { display: none; }
}

/* ---- Terminal CTA slide: "Dein What the Cake?!" ---------------------- */
/* Same footprint as a cake frame (aspect, shadow), but it is the bridge out
   of browsing: printed pattern field, the product-language stamp, and one
   primary action into the request form. */
.wtc-cta-card {
  position: relative;
  aspect-ratio: var(--wtc-aspect-cake);
  background: var(--wtc-surface-inverse);
  overflow: hidden;
  box-shadow: var(--wtc-elevation-frame);
  display: grid;
  place-content: center;
  justify-items: center;
  gap: var(--wtc-space-6);
  padding: var(--wtc-space-5);
}
.wtc-cta-card__pattern {
  position: absolute;
  inset: -30% -20%;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  align-content: center;
  transform: rotate(-6deg);
  font-family: var(--wtc-font-display);
  font-size: 1.25rem;
  text-transform: uppercase;
  color: var(--wtc-text-inverse);
  opacity: 0.16;
  pointer-events: none;
}
.wtc-cta-card__pattern .wtc-wordmark__mark { color: inherit; -webkit-text-stroke: 0; }
.wtc-cta-card__title {
  position: relative;
  background: var(--wtc-surface-aftershock);
  color: var(--wtc-text-primary);
  font-family: var(--wtc-font-display);
  font-size: clamp(1.5rem, 6vw, 2.5rem);
  line-height: 1.05;
  text-align: center;
  text-transform: uppercase;
  padding: 0.4em 0.6em;
  border: var(--wtc-border-width-print) solid var(--wtc-border-strong);
  box-shadow: var(--wtc-elevation-print);
  transform: rotate(var(--wtc-stamp-rotate-mark));
}
.wtc-cta-card__title .wtc-wordmark__mark { color: inherit; -webkit-text-stroke: 0; }
.wtc-cta-card .wtc-btn { position: relative; }

/* ---- Section heading ------------------------------------------------ */
.wtc-heading {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--wtc-space-3);
  margin-bottom: var(--wtc-space-6);
}

/* ---- Process step --------------------------------------------------- */
.wtc-step {
  display: grid;
  gap: var(--wtc-space-2);
  align-content: start;
  padding: var(--wtc-space-5);
  background: var(--wtc-surface-page);
  border: var(--wtc-border-width-rule) solid var(--wtc-border-strong);
}
.wtc-step__index { font-family: var(--wtc-font-label); font-size: var(--wtc-type-label-lg); letter-spacing: var(--wtc-tracking-label); color: var(--wtc-text-primary); }

/* ---- Request wizard (internal ref) ------------------------------ */
/* One form, four accordion steps. All wizard chrome is [data-js-only] and
   starts [hidden]; enhance.js reveals it per state. Expand/collapse is a
   plain display toggle — no height animation, nothing delays input in any
   motion mode. Without JS the list renders as the linear four-block form. */
.wtc-wizard { list-style: none; margin: 0; padding: 0; display: grid; }
.wtc-wstep { display: grid; gap: var(--wtc-space-3); padding-block: var(--wtc-space-4); }
.wtc-wstep:first-child { padding-top: 0; }
.wtc-wstep:last-child { padding-bottom: 0; }
.wtc-wstep + .wtc-wstep { border-top: var(--wtc-border-width-hair) solid var(--wtc-border-hairline); }
.wtc-wstep__body { display: grid; gap: var(--wtc-space-4); }
.wtc-wstep__index {
  flex: none;
  font-family: var(--wtc-font-label);
  font-size: var(--wtc-type-label-lg);
  letter-spacing: var(--wtc-tracking-label);
}
.wtc-wstep__name {
  flex: none;
  font-family: var(--wtc-font-label);
  font-size: var(--wtc-type-label);
  letter-spacing: var(--wtc-tracking-label);
  text-transform: uppercase;
}
/* Grid, not flex: the minmax(0, 1fr) answer track truly bottoms out at 0,
   so a long nowrap answer ellipsizes instead of propagating its full text
   width up the intrinsic-size chain (flex min-content would). */
.wtc-wstep__summary {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--wtc-space-3);
  width: 100%;
  min-height: var(--wtc-hit-min);
  padding: var(--wtc-space-2) 2px;
  background: none;
  border: none;
  font: inherit;
  color: inherit;
  text-align: start;
  cursor: pointer;
}
.wtc-wstep__answer {
  justify-self: start;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--wtc-type-body-small);
}
.wtc-wstep__edit {
  flex: none;
  font-family: var(--wtc-font-label);
  font-size: var(--wtc-type-label);
  letter-spacing: var(--wtc-tracking-label);
  text-transform: uppercase;
  text-decoration: underline;
  text-underline-offset: 0.35em;
}
.wtc-wstep__summary:hover .wtc-wstep__edit { color: var(--wtc-text-accent); }
.wtc-wstep__upcoming {
  display: flex;
  align-items: baseline;
  gap: var(--wtc-space-3);
  padding: var(--wtc-space-2) 2px;
  opacity: 0.45;
}
.wtc-wstep__progress { opacity: 0.6; }
.wtc-wstep__actions { display: flex; }

/* Torte/Muffins binary choice: two print-style options, native radios.
   The real input covers its whole option (opacity 0), so click/touch land
   on the native control and validation bubbles anchor to the visible box. */
.wtc-choice { border: 0; margin: 0; padding: 0; display: grid; gap: var(--wtc-space-2); }
.wtc-choice legend { padding: 0; }
.wtc-choice__options { display: flex; flex-wrap: wrap; gap: var(--wtc-space-3); }
.wtc-choice__option { position: relative; display: inline-flex; }
.wtc-choice__input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.wtc-choice__text {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--wtc-hit-min);
  padding-inline: var(--wtc-space-5);
  border: var(--wtc-border-width-rule) solid var(--wtc-border-strong);
  font-family: var(--wtc-font-label);
  font-size: var(--wtc-type-label-lg);
  letter-spacing: var(--wtc-tracking-label);
  text-transform: uppercase;
  transition: background var(--wtc-duration-ui) var(--wtc-ease-ui);
}
/* Accent background + inherited ink text: the same 4.55:1 AA pairing the
   motion-control's pressed state already uses. */
.wtc-choice__input:checked + .wtc-choice__text {
  background: var(--wtc-surface-accent);
  border-width: var(--wtc-border-width-print);
  font-weight: 700;
}
.wtc-choice__input:focus-visible + .wtc-choice__text {
  outline: var(--wtc-focus-width) solid var(--wtc-focus-ring);
  outline-offset: var(--wtc-focus-offset);
}

/* ---- Fields --------------------------------------------------------- */
.wtc-field { display: grid; gap: var(--wtc-space-2); }
.wtc-field__label { font-family: var(--wtc-font-label); font-size: var(--wtc-type-label); letter-spacing: var(--wtc-tracking-label); text-transform: uppercase; opacity: 0.75; }
.wtc-field__control {
  width: 100%;
  background: transparent;
  color: var(--wtc-text-primary);
  border: none;
  border-bottom: var(--wtc-border-width-rule) dashed var(--wtc-border-strong);
  padding: var(--wtc-space-2) 2px var(--wtc-space-3);
  font-family: var(--wtc-font-label);
  font-size: 0.9375rem;
  min-height: var(--wtc-hit-min);
}
textarea.wtc-field__control { resize: vertical; }

.wtc-form-card {
  background: var(--wtc-surface-page);
  color: var(--wtc-text-primary);
  padding: var(--wtc-space-5);
  border: var(--wtc-border-width-hair) solid var(--wtc-border-hairline);
  display: grid;
  gap: var(--wtc-space-5);
}
/* The card sits on a light field inside an inverse-surface section, so it
   needs its own link colour: the .wtc-surface--inverse a rule (foundation.css)
   would otherwise paint paper-coloured text on this paper background. */
.wtc-form-card a { color: var(--wtc-text-primary); }
.wtc-form-card a:hover { text-decoration-thickness: 2px; }
.wtc-status {
  border: var(--wtc-border-width-rule) dashed var(--wtc-border-strong);
  border-inline-start: var(--wtc-border-width-print) solid var(--wtc-surface-accent);
  padding: var(--wtc-space-3) var(--wtc-space-4);
  font-size: var(--wtc-type-body-small);
}
.wtc-status__key { color: var(--wtc-text-primary); font-weight: 700; }
.wtc-status--error { border-inline-start-color: var(--wtc-palette-magenta); }
.wtc-status--error .wtc-status__key { text-decoration: underline; }

/* ---- Footer --------------------------------------------------------- */
.wtc-footer {
  padding: var(--wtc-space-6) var(--wtc-gutter) var(--wtc-space-7);
  border-top: var(--wtc-border-width-rule) solid var(--wtc-border-strong);
  display: flex;
  flex-wrap: wrap;
  gap: var(--wtc-space-4) var(--wtc-space-6);
  justify-content: space-between;
  align-items: center;
  font-size: 0.75rem;
}
/* ---- Progressive enhancement ---------------------------------------- */
/* Without JS: no tease bands, no dead controls — the cake is simply visible. */
html:not(.js) [data-js-only] { display: none !important; }
html.js [data-no-js-only] { display: none !important; }
