/* ==========================================================================
   GripVid Component Library — "Wayfinding"
   --------------------------------------------------------------------------
   Prefix: wf-  (legacy styles.css uses gv-/blog-/footer-, so there is no
   collision while the two systems coexist.)

   Rules enforced throughout this file:
     · Every value comes from tokens.css. No hex, no magic numbers.
       The ONE exception is the 767px media-query breakpoint: CSS does not
       resolve var() inside @media, so it cannot be a token. It appears
       only in @media conditions, never as a property value.
     · Every interactive component defines default, hover, focus-visible,
       active, disabled and — where applicable — loading and error.
     · Orange is a surface. --ink sits on it. Orange as text is --signal-deep.
     · Tap targets are never below --tap-min.
     · Only the six approved animations appear here.

   Naming: .wf-block, .wf-block__element, .wf-block--modifier
   ========================================================================== */


/* ==========================================================================
   BUTTON
   Variants: --primary (default) --secondary --ghost --danger
   Sizes:    --sm --md (default) --lg
   States:   :hover :focus-visible :active :disabled .is-loading
   ========================================================================== */

.wf-btn {
  --_bg:     var(--signal);
  --_fg:     var(--text-on-signal);
  --_border: transparent;

  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);

  min-height: var(--tap-min);                       /* tap-target floor */
  padding: var(--s-3) var(--s-6);

  font-family: var(--font-display);
  font-size: var(--t-body-m);
  font-weight: var(--weight-semibold);
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;

  background: var(--_bg);
  color: var(--_fg);
  border: var(--border-width) solid var(--_border);
  border-radius: var(--radius-md);

  transition:
    background-color var(--dur-fast) var(--ease-movement),
    border-color     var(--dur-fast) var(--ease-movement),
    transform        var(--dur-instant) var(--ease-movement);
}

.wf-btn:hover              { background: color-mix(in srgb, var(--_bg) 88%, var(--ink)); box-shadow: var(--shadow-md); }
.wf-btn:active             { transform: scale(.98); }        /* approved animation #5 */
/* Primary carries a soft resting shadow so it reads as the page's main action */
.wf-btn:not(.wf-btn--secondary):not(.wf-btn--ghost) { box-shadow: var(--shadow-sm); }
.wf-btn--ghost:hover { box-shadow: none; }
.wf-btn:disabled,
.wf-btn[aria-disabled="true"] {
  background: var(--n-100);
  color: var(--text-disabled);
  border-color: transparent;
  transform: none;
  pointer-events: none;
}

.wf-btn--secondary { --_bg: var(--surface); --_fg: var(--text-primary); --_border: var(--border-hairline); }
.wf-btn--secondary:hover { background: var(--n-50); border-color: var(--n-300); }

.wf-btn--ghost { --_bg: transparent; --_fg: var(--signal-deep); --_border: transparent; }
.wf-btn--ghost:hover { background: var(--signal-soft); }

.wf-btn--danger { --_bg: var(--danger); --_fg: var(--surface); }

.wf-btn--sm { min-height: var(--tap-min); padding: var(--s-2) var(--s-4); font-size: var(--t-body-s); }
.wf-btn--lg { min-height: var(--control-h-lg); padding: var(--s-4) var(--s-8); font-size: var(--t-body-l); }

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

/* Loading: the label stays in flow so the button cannot change width. */
.wf-btn.is-loading            { pointer-events: none; }
.wf-btn.is-loading .wf-btn__label { visibility: hidden; }
.wf-btn.is-loading::after {
  content: "";
  position: absolute;
  width: var(--icon-sm); height: var(--icon-sm);
  border: var(--border-width-strong) solid currentColor;
  border-top-color: transparent;
  border-radius: var(--radius-pill);
  animation: wf-spin var(--dur-slow) linear infinite;
}
@keyframes wf-spin { to { transform: rotate(360deg); } }

.wf-btn__icon { flex-shrink: 0; width: var(--icon-sm); height: var(--icon-sm); }


/* ==========================================================================
   THE SLOT — the signature component.
   A single bar that resolves as a link is pasted: the chip flips from neutral
   to the detected platform, the border shifts from ink to orange, and the
   action button becomes live.
   States: (default) .is-detected .is-invalid
   ========================================================================== */

.wf-slot {
  /* Softer resting edge: the 2px ink outline read as stark. Depth now comes
     from the shadow; the edge only takes colour for detected / invalid. */
  --_edge: var(--n-200);

  display: flex;
  align-items: stretch;
  gap: 0;
  width: 100%;
  overflow: hidden;

  background: var(--surface);
  border: var(--border-width-strong) solid var(--_edge);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);

  transition: border-color var(--dur-base) var(--ease-movement),
              box-shadow   var(--dur-base) var(--ease-movement);
}
.wf-slot:focus-within { box-shadow: var(--shadow-lg), var(--focus-ring); }
.wf-slot.is-detected  { --_edge: var(--signal); }
.wf-slot.is-invalid   { --_edge: var(--danger); }

/* Leading chip — neutral link glyph until a platform is recognised. */
.wf-slot__chip {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: var(--control-h-md);
  color: var(--text-muted);
  border-inline-end: var(--border-width) solid var(--border-subtle);
  transition: color var(--dur-base) var(--ease-entrance);
}
.wf-slot.is-detected .wf-slot__chip { color: var(--signal-deep); }
.wf-slot__chip svg { width: var(--icon-md); height: var(--icon-md); }

/* Approved animation #1 — the chip resolving. */
.wf-slot.is-detected .wf-slot__chip svg { animation: wf-chip-in var(--dur-base) var(--ease-entrance); }
@keyframes wf-chip-in {
  from { opacity: 0; transform: translateY(4px) scale(.85); }
  to   { opacity: 1; transform: none; }
}

.wf-slot__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: var(--s-4);
  font-family: var(--font-body);         /* body face — mono read as techy here */
  font-size: var(--t-input-min);         /* 16px floor — stops iOS zoom */
  color: var(--text-primary);
  background: transparent;
  border: 0;
  min-height: var(--control-h-xl);
}
.wf-slot__input::placeholder { color: var(--text-disabled); font-family: var(--font-body); }
.wf-slot__input:focus { outline: none; }   /* the ring is on the wrapper */

.wf-slot__paste,
.wf-slot__clear {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-width: var(--tap-min);
  padding-inline: var(--s-4);
  font-family: var(--font-display);
  font-size: var(--t-body-s);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
  background: transparent;
  border: 0;
  border-inline-start: var(--border-width) solid var(--border-subtle);
  transition: background-color var(--dur-fast) var(--ease-movement);
}
.wf-slot__paste:hover,
.wf-slot__clear:hover { background: var(--n-50); color: var(--text-primary); }

.wf-slot__action {
  flex-shrink: 0;
  padding-inline: var(--s-8);
  font-family: var(--font-display);
  font-size: var(--t-body-m);
  font-weight: var(--weight-bold);
  color: var(--text-on-signal);
  background: var(--signal);
  border: 0;
  transition: background-color var(--dur-fast) var(--ease-movement),
              transform        var(--dur-instant) var(--ease-movement);
}
.wf-slot__action:hover  { background: color-mix(in srgb, var(--signal) 88%, var(--ink)); }
.wf-slot__action:active { transform: scale(.98); }
.wf-slot__action:disabled { background: var(--n-100); color: var(--text-disabled); pointer-events: none; }

/* Mono readout beneath the bar: platform · type · state */
.wf-slot-readout {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-3);
  min-height: 1.4em;                       /* reserved so nothing shifts */
  font-family: var(--font-mono);
  font-size: var(--t-data);
  letter-spacing: var(--t-data-ls);
  color: var(--text-muted);
}
.wf-slot-readout--ok      { color: var(--trust); }
.wf-slot-readout--invalid { color: var(--danger); }

/* Mobile: the bar becomes a stack. Paste is a full-width primary affordance
   because mobile users paste — they do not type URLs. */
@media (max-width: 767px) {
  .wf-slot { flex-wrap: wrap; }
  .wf-slot__chip  { width: var(--tap-min); border-inline-end: 0; }
  .wf-slot__input { flex: 1 1 60%; min-height: var(--control-h-md); }
  .wf-slot__paste { order: 3; flex: 1 1 100%;
                    min-height: var(--control-h-md); border-inline-start: 0;
                    border-top: var(--border-width) solid var(--border-subtle); }
  .wf-slot__action { order: 4; flex: 1 1 100%; min-height: var(--control-h-lg);
                     border-radius: 0 0 var(--radius-sm) var(--radius-sm); }
}


/* ==========================================================================
   CARD
   ========================================================================== */

.wf-card {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding: var(--s-6);
  background: var(--surface);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-lg);
}
.wf-card--raised   { border-color: transparent; box-shadow: var(--shadow-md); }
.wf-card--link     { text-decoration: none; color: inherit;
                     transition: border-color var(--dur-fast) var(--ease-movement),
                                 box-shadow   var(--dur-fast) var(--ease-movement); }
.wf-card--link:hover { border-color: var(--n-300); box-shadow: var(--shadow-md); }
.wf-card__title { font-family: var(--font-display); font-size: var(--t-heading-m);
                  font-weight: var(--weight-semibold); }
.wf-card__body  { color: var(--text-secondary); }


/* ==========================================================================
   PLATFORM BADGE / CHIP
   ========================================================================== */

.wf-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-1) var(--s-3);
  font-family: var(--font-display);
  font-size: var(--t-eyebrow);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--t-eyebrow-ls);
  text-transform: uppercase;
  color: var(--text-secondary);
  background: var(--n-50);
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-pill);
}
.wf-badge--signal { color: var(--signal-deep); background: var(--signal-soft); border-color: var(--signal-border); }
.wf-badge--trust  { color: var(--trust);       background: var(--trust-soft);  border-color: transparent; }
.wf-badge--danger { color: var(--danger);      background: var(--danger-soft); border-color: transparent; }
.wf-badge svg { width: var(--icon-xs); height: var(--icon-xs); }


/* ==========================================================================
   FORMAT / QUALITY ROW
   The recommended option is visually obvious; MP3 is a peer choice, never a
   buried dropdown item.
   ========================================================================== */

.wf-formats { display: flex; flex-direction: column; gap: var(--s-2); }

.wf-format {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: var(--s-4);
  width: 100%;
  min-height: var(--control-h-lg);
  padding: var(--s-3) var(--s-4);
  text-align: start;
  background: var(--surface);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-md);
  transition: border-color var(--dur-fast) var(--ease-movement),
              background-color var(--dur-fast) var(--ease-movement);
}
.wf-format:hover { border-color: var(--n-300); background: var(--n-50); }
.wf-format--recommended { border-color: var(--signal); border-width: var(--border-width-strong); }
.wf-format--recommended::before {
  content: "Recommended";
  grid-column: 1 / -1;
  font-family: var(--font-display);
  font-size: var(--t-eyebrow);
  letter-spacing: var(--t-eyebrow-ls);
  text-transform: uppercase;
  color: var(--signal-deep);
}
.wf-format__res   { font-family: var(--font-mono); font-weight: var(--weight-medium);
                    font-variant-numeric: tabular-nums; color: var(--text-primary); }
.wf-format__meta  { font-family: var(--font-mono); font-size: var(--t-body-s);
                    color: var(--text-muted); font-variant-numeric: tabular-nums; }
.wf-format__size  { font-family: var(--font-mono); font-variant-numeric: tabular-nums;
                    color: var(--text-secondary); }

/* Approved animation #2 — rows stagger in as results arrive. */
.wf-format.is-entering { animation: wf-row-in var(--dur-base) var(--ease-entrance) backwards; }
.wf-format.is-entering:nth-child(1) { animation-delay: calc(var(--stagger-step) * 0); }
.wf-format.is-entering:nth-child(2) { animation-delay: calc(var(--stagger-step) * 1); }
.wf-format.is-entering:nth-child(3) { animation-delay: calc(var(--stagger-step) * 2); }
.wf-format.is-entering:nth-child(4) { animation-delay: calc(var(--stagger-step) * 3); }
.wf-format.is-entering:nth-child(5) { animation-delay: calc(var(--stagger-step) * 4); }
.wf-format.is-entering:nth-child(6) { animation-delay: calc(var(--stagger-step) * 5); }
@keyframes wf-row-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

@media (max-width: 767px) {
  /* Two columns: quality/chips/size stack left, the download button sits
     full-height on the right — thumb-reachable without hunting. */
  .wf-format { grid-template-columns: 1fr auto; row-gap: var(--s-1); }
  .wf-format__chips { grid-column: 1; }
  .wf-format__size  { grid-column: 1; }
  .wf-format__get   { grid-column: 2; grid-row: 1 / span 3; align-self: center; }
  .wf-format--recommended .wf-format__get { grid-row: 2 / span 3; }
}


/* ==========================================================================
   SKELETON — mirrors the real result card so the layout never shifts (CLS 0)
   ========================================================================== */

.wf-skeleton {
  background: linear-gradient(90deg, var(--n-100) 25%, var(--n-50) 37%, var(--n-100) 63%);
  background-size: 400% 100%;
  border-radius: var(--radius-sm);
  animation: wf-shimmer var(--dur-shimmer) ease-in-out infinite;
}
@keyframes wf-shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }
@media (prefers-reduced-motion: reduce) {
  .wf-skeleton { animation: none; background: var(--n-100); }
}
.wf-skeleton--text  { height: 1em; margin-block: .25em; }
.wf-skeleton--title { height: 1.6em; width: 65%; }
.wf-skeleton--thumb { width: 100%; aspect-ratio: 16 / 9; border-radius: var(--radius-md); }
.wf-skeleton--row   { height: var(--control-h-lg); border-radius: var(--radius-md); }
/* Mirrors .wf-format--recommended, which is taller by its "Recommended" label. */
.wf-skeleton--row-rec { height: calc(var(--control-h-lg) + var(--s-8) + var(--s-1)); }


/* ==========================================================================
   ACCORDION — real <button> semantics, keyboard operable
   ========================================================================== */

.wf-accordion { border-top: var(--border-width) solid var(--border-hairline); }
.wf-accordion__item { border-bottom: var(--border-width) solid var(--border-hairline); }

.wf-accordion__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  width: 100%;
  min-height: var(--control-h-lg);
  padding: var(--s-4) 0;
  text-align: start;
  font-family: var(--font-display);
  font-size: var(--t-body-l);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  background: transparent;
  border: 0;
}
.wf-accordion__trigger:hover { color: var(--signal-deep); }

.wf-accordion__icon {
  flex-shrink: 0;
  width: var(--icon-md); height: var(--icon-md);
  color: var(--text-muted);
  transition: transform var(--dur-base) var(--ease-movement);   /* approved #4 */
}
.wf-accordion__trigger[aria-expanded="true"] .wf-accordion__icon { transform: rotate(180deg); }

.wf-accordion__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-base) var(--ease-movement);
}
.wf-accordion__trigger[aria-expanded="true"] + .wf-accordion__panel { grid-template-rows: 1fr; }
.wf-accordion__panel > div { overflow: hidden; }
.wf-accordion__content { padding-bottom: var(--s-5); color: var(--text-secondary); max-width: var(--measure); }


/* ==========================================================================
   TABS
   ========================================================================== */

.wf-tabs { display: flex; gap: var(--s-1); border-bottom: var(--border-width) solid var(--border-hairline);
           overflow-x: auto; }
.wf-tab {
  min-height: var(--tap-min);
  padding: var(--s-3) var(--s-4);
  font-family: var(--font-display);
  font-size: var(--t-body-m);
  font-weight: var(--weight-semibold);
  white-space: nowrap;
  color: var(--text-muted);
  background: transparent;
  border: 0;
  border-bottom: var(--border-width-strong) solid transparent;
  margin-bottom: calc(var(--border-width) * -1);
  transition: color var(--dur-fast) var(--ease-movement),
              border-color var(--dur-fast) var(--ease-movement);
}
.wf-tab:hover { color: var(--text-primary); }
.wf-tab[aria-selected="true"] { color: var(--text-primary); border-bottom-color: var(--signal); }


/* ==========================================================================
   PROGRESS — honest. Indeterminate is visually distinct from real progress.
   ========================================================================== */

.wf-progress {
  width: 100%;
  height: var(--progress-h);
  background: var(--n-100);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.wf-progress__fill {
  height: 100%;
  width: 0%;
  background: var(--signal);
  border-radius: inherit;
  transition: width var(--dur-base) var(--ease-movement);      /* approved #3 */
}
.wf-progress--indeterminate .wf-progress__fill {
  width: 35%;
  animation: wf-indeterminate var(--dur-indeterminate) var(--ease-movement) infinite;
}
@keyframes wf-indeterminate {
  from { transform: translateX(-100%); }
  to   { transform: translateX(340%); }
}
.wf-progress-meta {
  display: flex; justify-content: space-between;
  margin-top: var(--s-2);
  font-family: var(--font-mono); font-size: var(--t-data);
  font-variant-numeric: tabular-nums; color: var(--text-muted);
}


/* ==========================================================================
   TOAST
   ========================================================================== */

.wf-toast-region {
  position: fixed;
  left: 50%; transform: translateX(-50%);
  bottom: calc(var(--s-6) + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: var(--s-2);
  width: min(28rem, calc(100vw - var(--s-8)));
  z-index: var(--z-toast);
  pointer-events: none;
}
.wf-toast {
  display: flex; align-items: flex-start; gap: var(--s-3);
  padding: var(--s-4);
  background: var(--ink);
  color: var(--ground);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  pointer-events: auto;
}
.wf-toast--ok     { background: var(--trust); }
.wf-toast--danger { background: var(--danger); }
.wf-toast__title  { font-family: var(--font-display); font-weight: var(--weight-semibold); }
.wf-toast__body   { font-size: var(--t-body-s); opacity: .9; }


/* ==========================================================================
   SHEET / MODAL — <dialog>, so focus trapping and Esc come from the platform
   ========================================================================== */

.wf-sheet {
  width: min(32rem, calc(100vw - var(--s-8)));
  padding: var(--s-6);
  background: var(--surface);
  color: var(--text-primary);
  border: 0;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}
.wf-sheet::backdrop { background: var(--backdrop); }
.wf-sheet__head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
                  margin-bottom: var(--s-4); }

/* Mobile: bottom sheet, respecting the home indicator. */
@media (max-width: 767px) {
  .wf-sheet {
    width: 100vw; max-width: none;
    margin: auto auto 0;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    padding-bottom: calc(var(--s-6) + env(safe-area-inset-bottom));
  }
}


/* ==========================================================================
   TOOLTIP — the trigger must carry the real accessible label
   ========================================================================== */

.wf-tip { position: relative; display: inline-flex; }
.wf-tip__bubble {
  position: absolute;
  bottom: calc(100% + var(--s-2));
  left: 50%; transform: translateX(-50%);
  padding: var(--s-2) var(--s-3);
  font-size: var(--t-body-s);
  white-space: nowrap;
  color: var(--ground);
  background: var(--ink);
  border-radius: var(--radius-sm);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease-movement);
}
.wf-tip:hover .wf-tip__bubble,
.wf-tip:focus-within .wf-tip__bubble { opacity: 1; }


/* ==========================================================================
   BREADCRUMBS
   ========================================================================== */

.wf-crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2);
             font-size: var(--t-body-s); color: var(--text-muted); }
.wf-crumbs a {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--tap-min);   /* the bare link is only 22px tall */
  min-width: var(--tap-min);    /* "Home" is only 39px wide */
  color: var(--text-secondary); text-decoration: none;
}
.wf-crumbs a:hover { color: var(--signal-deep); text-decoration: underline; }
.wf-crumbs__sep { color: var(--text-disabled); }
.wf-crumbs__current { color: var(--text-primary); font-weight: var(--weight-medium); }


/* ==========================================================================
   EMPTY / ERROR STATES
   Errors state what happened and what to do. They do not apologise.
   ========================================================================== */

.wf-state {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-3);
  padding: var(--s-6);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.wf-state__icon  { width: var(--icon-xl); height: var(--icon-xl); color: var(--text-muted); }
.wf-state__title { font-family: var(--font-display); font-size: var(--t-heading-m);
                   font-weight: var(--weight-semibold); }
.wf-state__body  { color: var(--text-secondary); max-width: var(--measure); }

.wf-state--error { border-color: var(--danger); background: var(--danger-soft); }
.wf-state--error .wf-state__icon { color: var(--danger); }
.wf-state--warn  { border-color: transparent; background: var(--warn-soft); }
.wf-state--warn  .wf-state__icon { color: var(--warn); }
.wf-state--ok    { border-color: transparent; background: var(--trust-soft); }
.wf-state--ok    .wf-state__icon { color: var(--trust); }


/* ==========================================================================
   FEATURE / STEP / BLOG CARDS
   ========================================================================== */

.wf-feature { display: flex; flex-direction: column; gap: var(--s-2); }
/* Icon sits in a soft warm chip rather than floating bare on the page */
.wf-feature__icon  {
  width: calc(var(--icon-lg) + var(--s-4));
  height: calc(var(--icon-lg) + var(--s-4));
  padding: var(--s-2);
  color: var(--signal-deep);
  background: var(--signal-soft);
  border-radius: var(--radius-md);
  margin-bottom: var(--s-1);
}
.wf-feature__title { font-family: var(--font-display); font-size: var(--t-body-l);
                     font-weight: var(--weight-semibold); }
.wf-feature__body  { color: var(--text-secondary); font-size: var(--t-body-s); }

.wf-step { display: flex; flex-direction: column; gap: var(--s-3); }
.wf-step__num {
  font-family: var(--font-display);
  font-size: var(--t-display-l);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--signal);
}
.wf-step__rule  { height: var(--border-width); background: var(--border-hairline); }
.wf-step__title { font-family: var(--font-display); font-size: var(--t-heading-m);
                  font-weight: var(--weight-semibold);
                  letter-spacing: -0.01em; }
.wf-step__body  { color: var(--text-secondary); }

.wf-blogcard { display: flex; flex-direction: column; gap: var(--s-3);
               text-decoration: none; color: inherit; }
.wf-blogcard__media { width: 100%; aspect-ratio: 16 / 9; object-fit: cover;
                      border-radius: var(--radius-md); background: var(--n-100); }
.wf-blogcard__title { font-family: var(--font-display); font-size: var(--t-heading-m);
                      font-weight: var(--weight-semibold); }
.wf-blogcard:hover .wf-blogcard__title { color: var(--signal-deep); }
.wf-blogcard__meta  { font-family: var(--font-mono); font-size: var(--t-body-s);
                      color: var(--text-muted); }


/* ==========================================================================
   TABLE — scrolls inside its own container; the page never scrolls sideways
   ========================================================================== */

.wf-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch;
                 border: var(--border-width) solid var(--border-hairline);
                 border-radius: var(--radius-md); }
.wf-table { width: 100%; border-collapse: collapse; font-size: var(--t-body-s); }
.wf-table th, .wf-table td { padding: var(--s-3) var(--s-4); text-align: start;
                             border-bottom: var(--border-width) solid var(--border-subtle); }
.wf-table th { font-family: var(--font-display); font-size: var(--t-eyebrow);
               letter-spacing: var(--t-eyebrow-ls); text-transform: uppercase;
               color: var(--text-muted); background: var(--n-50); white-space: nowrap; }
.wf-table td.is-data { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.wf-table tr:last-child td { border-bottom: 0; }


/* ==========================================================================
   PLATFORM GRID
   ========================================================================== */

.wf-platform-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--platform-card-min), 1fr));
  gap: var(--s-3);
}
/* Horizontal chips — real logo left, name right. The stacked version wasted
   vertical space and left the logo floating. */
.wf-platform-card {
  display: flex; align-items: center; gap: var(--s-3);
  min-height: var(--control-h-lg);
  padding: var(--s-3) var(--s-4);
  text-decoration: none;
  color: var(--text-primary);
  background: var(--surface);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  transition: border-color var(--dur-fast) var(--ease-movement),
              box-shadow   var(--dur-fast) var(--ease-movement),
              transform    var(--dur-fast) var(--ease-movement);
}
.wf-platform-card:hover { border-color: var(--n-300); box-shadow: var(--shadow-md); transform: translateY(-1px); }
.wf-platform-card__icon {
  display: inline-flex; flex-shrink: 0;
  width: var(--icon-lg); height: var(--icon-lg);
}
.wf-platform-card__icon svg { width: 100%; height: 100%; }
.wf-platform-card__name { font-family: var(--font-display); font-weight: var(--weight-semibold); }

@media (max-width: 767px) {
  .wf-platform-grid { grid-template-columns: repeat(2, 1fr); gap: var(--s-2); }
  .wf-platform-card { min-height: var(--control-h-md); padding: var(--s-2) var(--s-3); }
  .wf-platform-card__name { font-size: var(--t-body-s); }
}


/* ==========================================================================
   STICKY MOBILE CTA — appears once the hero has scrolled away
   ========================================================================== */

.wf-sticky-cta {
  position: fixed;
  left: 0; right: 0;
  bottom: 0;
  z-index: var(--z-sticky);
  display: none;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4);
  padding-bottom: calc(var(--s-3) + env(safe-area-inset-bottom));
  background: var(--surface);
  border-top: var(--border-width) solid var(--border-hairline);
  box-shadow: var(--shadow-lg);
  transform: translateY(100%);
  transition: transform var(--dur-base) var(--ease-movement);
}
.wf-sticky-cta.is-visible { transform: none; }
@media (max-width: 767px) { .wf-sticky-cta { display: flex; } }


/* ==========================================================================
   SKIP LINK — the first focusable element on every page
   ========================================================================== */

.wf-skip {
  position: absolute;
  inset-inline-start: var(--s-4);
  top: 0;
  z-index: calc(var(--z-toast) + 1);
  padding: var(--s-3) var(--s-4);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  color: var(--ground);
  background: var(--ink);
  border-radius: var(--radius-md);
  text-decoration: none;
  transform: translateY(-150%);
  transition: transform var(--dur-fast) var(--ease-movement);
}
/* :focus, not :focus-visible — a skip link must appear for ANY focus, including
   programmatic focus and engines whose focus-visible heuristics differ. */
.wf-skip:focus { transform: translateY(var(--s-4)); }


/* ==========================================================================
   HEADER
   ========================================================================== */

.wf-header {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  background: var(--ground);
  border-bottom: var(--border-width) solid var(--border-hairline);
  transition: box-shadow var(--dur-fast) var(--ease-movement);
}
.wf-header.is-scrolled { box-shadow: var(--shadow-sm); }

.wf-header__inner {
  display: flex;
  align-items: center;
  gap: var(--s-6);
  min-height: var(--header-h);
}

.wf-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  min-height: var(--tap-min);   /* the mark alone is only 28px tall */
  text-decoration: none;
  color: var(--text-primary);
  flex-shrink: 0;
}
.wf-brand__mark { width: var(--icon-xl); height: var(--icon-xl); border-radius: var(--radius-sm); }
.wf-brand__name {
  font-family: var(--font-display);
  font-size: var(--t-body-l);
  font-weight: var(--weight-bold);
  letter-spacing: -0.02em;
}

/* Desktop nav ------------------------------------------------------------ */
.wf-nav { display: flex; align-items: center; gap: var(--s-1); margin-inline-start: auto; }

.wf-nav__link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: var(--tap-min);
  padding: var(--s-2) var(--s-3);
  font-family: var(--font-display);
  font-size: var(--t-body-s);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
  text-decoration: none;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-movement),
              background-color var(--dur-fast) var(--ease-movement);
}
.wf-nav__link:hover { color: var(--text-primary); background: var(--n-50); }
.wf-nav__link[aria-current="page"] { color: var(--signal-deep); }

/* Platforms dropdown ----------------------------------------------------- */
.wf-menu { position: relative; }
.wf-menu__caret { width: var(--icon-xs); height: var(--icon-xs);
                  transition: transform var(--dur-fast) var(--ease-movement); }
.wf-menu__trigger[aria-expanded="true"] .wf-menu__caret { transform: rotate(180deg); }
.wf-menu__trigger[aria-expanded="true"] { color: var(--text-primary); background: var(--n-50); }

.wf-menu__panel {
  position: absolute;
  top: calc(100% + var(--s-2));
  inset-inline-end: 0;
  display: none;
  grid-template-columns: repeat(2, minmax(9rem, 1fr));
  gap: var(--s-1);
  padding: var(--s-2);
  background: var(--surface);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
}
.wf-menu__trigger[aria-expanded="true"] + .wf-menu__panel { display: grid; }

.wf-menu__link {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  min-height: var(--tap-min);
  padding: var(--s-2) var(--s-3);
  font-size: var(--t-body-s);
  color: var(--text-secondary);
  text-decoration: none;
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
.wf-menu__link:hover { color: var(--text-primary); background: var(--n-50); }
.wf-menu__link svg { width: var(--icon-md); height: var(--icon-md); flex-shrink: 0; color: var(--text-disabled); }
.wf-menu__link:hover svg { color: var(--signal-deep); }

/* Hamburger -------------------------------------------------------------- */
.wf-burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: var(--s-1);
  width: var(--tap-min);
  height: var(--tap-min);
  margin-inline-start: auto;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
}
.wf-burger span {
  display: block;
  width: var(--icon-md);
  height: var(--border-width-strong);
  margin-inline: auto;
  background: var(--text-primary);
  border-radius: var(--radius-pill);
}

@media (max-width: 900px) {
  .wf-nav    { display: none; }
  .wf-burger { display: flex; }
  /* The nav carried the auto margin on desktop; with it hidden the end group
     has to take over or the burger collapses back against the logo. */
  .wf-header__end { margin-inline-start: auto; }
}


/* ==========================================================================
   MOBILE DRAWER — native <dialog>, so focus trapping, Esc and background
   inertness come from the platform rather than hand-written JS.
   ========================================================================== */

.wf-drawer {
  width: min(22rem, 88vw);
  max-width: none;
  height: 100%;
  max-height: 100%;
  margin: 0 0 0 auto;                       /* sits against the right edge */
  padding: 0;
  background: var(--ground);
  color: var(--text-primary);
  border: 0;
  box-shadow: var(--shadow-lg);
}
.wf-drawer::backdrop { background: var(--backdrop); }

.wf-drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  min-height: var(--header-h);
  padding-inline: var(--s-4);
  border-bottom: var(--border-width) solid var(--border-hairline);
}
.wf-drawer__close {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--tap-min); height: var(--tap-min);
  color: var(--text-secondary);
  background: transparent; border: 0; border-radius: var(--radius-sm);
}
.wf-drawer__close:hover { background: var(--n-50); color: var(--text-primary); }
.wf-drawer__close svg { width: var(--icon-md); height: var(--icon-md); }

.wf-drawer__body {
  overflow-y: auto;
  height: calc(100% - var(--header-h));
  padding: var(--s-4);
  padding-bottom: calc(var(--s-8) + env(safe-area-inset-bottom));
}
.wf-drawer__group + .wf-drawer__group { margin-top: var(--s-6); }
.wf-drawer__label {
  display: block;
  margin-bottom: var(--s-2);
  font-family: var(--font-display);
  font-size: var(--t-eyebrow);
  letter-spacing: var(--t-eyebrow-ls);
  text-transform: uppercase;
  color: var(--text-muted);
}
.wf-drawer__link {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: var(--control-h-md);
  padding: var(--s-2) var(--s-3);
  font-family: var(--font-display);
  font-size: var(--t-body-m);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  text-decoration: none;
  border-radius: var(--radius-sm);
}
.wf-drawer__link:hover { background: var(--n-50); }
.wf-drawer__link svg { width: var(--icon-md); height: var(--icon-md); color: var(--text-disabled); flex-shrink: 0; }
.wf-drawer__grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s-1); }


/* ==========================================================================
   FOOTER
   ========================================================================== */

.wf-footer {
  margin-top: var(--s-10);
  padding-block: var(--s-10) var(--s-6);
  background: var(--n-50);
  border-top: var(--border-width) solid var(--border-hairline);
}

.wf-footer__top {
  display: grid;
  grid-template-columns: 1.5fr repeat(3, 1fr);
  gap: var(--s-10) var(--s-8);
}
.wf-footer__tagline { color: var(--text-secondary); font-size: var(--t-body-s); max-width: 30ch; }
.wf-footer__mail {
  display: inline-flex; align-items: center; gap: var(--s-2);
  min-height: var(--tap-min);
  font-family: var(--font-mono); font-size: var(--t-body-s);
  color: var(--text-secondary); text-decoration: none;
}
.wf-footer__mail:hover { color: var(--signal-deep); }
.wf-footer__mail svg { width: var(--icon-sm); height: var(--icon-sm); }

.wf-footer__title {
  margin-bottom: var(--s-3);
  font-family: var(--font-display);
  font-size: var(--t-eyebrow);
  letter-spacing: var(--t-eyebrow-ls);
  text-transform: uppercase;
  color: var(--text-muted);
}
.wf-footer__list { list-style: none; margin: 0; padding: 0; }
.wf-footer__list a {
  display: inline-flex; align-items: center;
  min-height: var(--tap-min);
  min-width: var(--tap-min);   /* short labels ("FAQ", "Blog") are ~27px wide otherwise */
  font-size: var(--t-body-s);
  color: var(--text-secondary);
  text-decoration: none;
}
.wf-footer__list a:hover { color: var(--signal-deep); text-decoration: underline; }

.wf-footer__rule { height: var(--border-width); margin-block: var(--s-8); background: var(--border-hairline); }

.wf-footer__bottom {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--s-4);
  font-size: var(--t-body-s); color: var(--text-muted);
}
.wf-footer__legal { display: flex; flex-wrap: wrap; gap: var(--s-4); }
.wf-footer__legal a {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--tap-min);
  min-width: var(--tap-min);    /* short words like "DMCA" are otherwise ~27px wide */
  color: var(--text-muted); text-decoration: none;
}
.wf-footer__legal a:hover { color: var(--signal-deep); text-decoration: underline; }

@media (max-width: 900px) {
  .wf-footer__top { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 767px) {
  .wf-footer__top { grid-template-columns: 1fr; gap: var(--s-8); }
  .wf-footer__bottom { flex-direction: column; align-items: flex-start; }
}


/* ==========================================================================
   BREADCRUMB BAR
   ========================================================================== */

.wf-crumbs-bar {
  padding-block: var(--s-3);
  border-bottom: var(--border-width) solid var(--border-subtle);
}


/* ==========================================================================
   HERO
   The ground is flat and honest. There is no ambient gradient: the visual
   interest comes from typographic scale and rules, so nothing competes with
   the Slot — which is the entire product.
   ========================================================================== */

.wf-hero {
  padding-block: var(--s-12) var(--s-10);
  border-bottom: var(--border-width) solid var(--border-hairline);
  text-align: center;
  /* A faint warm wash behind the headline. Barely-there on purpose: enough to
     lift the hero off the page, never competing with the input. */
  background: radial-gradient(52rem 22rem at 50% -6rem,
              color-mix(in srgb, var(--signal) 8%, transparent), transparent 70%);
}
.wf-hero__eyebrow { margin-bottom: var(--s-3); }

.wf-hero__title {
  max-width: 20ch;
  margin-inline: auto;
  margin-bottom: var(--s-5);
}

.wf-hero__sub {
  max-width: 46ch;
  margin-inline: auto;
  margin-bottom: var(--s-8);
  font-size: var(--t-body-l);
  line-height: var(--t-body-l-lh);
  color: var(--text-secondary);
}

.wf-hero__slot { max-width: 44rem; margin-inline: auto; }
.wf-hero .wf-slot-readout { justify-content: center; }

/* Recognisable platform marks in their brand colours (contrast-corrected
   server-side). The monochrome version read as meaningless grey shapes. */
.wf-hero__marks {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-2);
  margin: var(--s-8) auto var(--s-4);
  padding: 0;
  list-style: none;
}
.wf-hero__marks a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-min);
  height: var(--tap-min);
  background: var(--surface);
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-fast) var(--ease-movement),
              box-shadow var(--dur-fast) var(--ease-movement);
}
.wf-hero__marks a:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.wf-hero__marks svg { width: var(--icon-md); height: var(--icon-md); }

.wf-hero__trust {
  font-size: var(--t-body-s);
  color: var(--text-muted);
}

@media (max-width: 767px) {
  .wf-hero { padding-block: var(--s-8) var(--s-6); }
  .wf-hero__title { max-width: 100%; }
}


/* ==========================================================================
   SECTION HEADINGS
   ========================================================================== */

.wf-section__title { margin-bottom: var(--s-6); max-width: 22ch; }


/* ==========================================================================
   STEPS — the ruled, numbered sequence
   ========================================================================== */

.wf-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-8);
  margin: 0;
  padding: 0;
  list-style: none;
}
@media (max-width: 767px) {
  .wf-steps { grid-template-columns: 1fr; gap: var(--s-8); }
}


/* ==========================================================================
   FEATURE GRID
   ========================================================================== */

.wf-features {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-8) var(--s-6);
}
@media (max-width: 1023px) { .wf-features { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 767px)  { .wf-features { grid-template-columns: 1fr; gap: var(--s-8); } }


/* ==========================================================================
   QUALITY LADDER
   ========================================================================== */

.wf-ladder {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin: 0 0 var(--s-5);
  padding: 0;
  list-style: none;
  counter-reset: none;
}
.wf-ladder__step {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  flex: 1 1 8rem;
  min-height: calc(var(--control-h-lg) + var(--s-4));
  padding: var(--s-3) var(--s-4);
  background: var(--surface);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-md);
}
.wf-ladder__step.is-recommended {
  border-color: var(--signal);
  border-width: var(--border-width-strong);
}
.wf-ladder__step--audio { border-style: dashed; }
.wf-ladder__res {
  font-family: var(--font-mono);
  font-size: var(--t-body-l);
  font-weight: var(--weight-medium);
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}
.wf-ladder__note { font-size: var(--t-body-s); color: var(--text-muted); }
.wf-ladder__caption {
  max-width: var(--measure);
  font-size: var(--t-body-s);
  color: var(--text-muted);
}
@media (max-width: 767px) {
  .wf-ladder__step { flex: 1 1 calc(50% - var(--s-2)); }
}


/* ==========================================================================
   FAQ tail link
   ========================================================================== */

.wf-faq__more { margin-top: var(--s-6); font-size: var(--t-body-s); }

/* Category jump-links — 22 questions is too many to scroll blind */
.wf-faq-nav {
  position: sticky;
  top: var(--header-h);
  z-index: calc(var(--z-nav) - 1);
  padding-block: var(--s-3);
  background: var(--ground);
  border-bottom: var(--border-width) solid var(--border-hairline);
}
.wf-faq-nav ul {
  display: flex; flex-wrap: wrap; gap: var(--s-2);
  margin: 0; padding: 0; list-style: none;
}
.wf-faq-nav a {
  display: inline-flex; align-items: center;
  min-height: var(--tap-min);
  padding-inline: var(--s-3);
  font-family: var(--font-display);
  font-size: var(--t-body-s);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
  text-decoration: none;
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-pill);
}
.wf-faq-nav a:hover { color: var(--signal-deep); border-color: var(--signal); }

.wf-faq-group + .wf-faq-group { margin-top: var(--s-10); }
/* Offset anchor jumps so headings do not land under the sticky bars */
.wf-faq-group { scroll-margin-top: calc(var(--header-h) * 2 + var(--s-4)); }
.wf-faq__more a { display: inline-flex; align-items: center; min-height: var(--tap-min); }


/* ==========================================================================
   CLOSING CTA
   ========================================================================== */

.wf-closing {
  border-top: var(--border-width) solid var(--border-hairline);
  text-align: start;
}
.wf-closing__title { margin-bottom: var(--s-3); }
.wf-closing__sub {
  max-width: var(--measure);
  margin-bottom: var(--s-6);
  font-size: var(--t-body-l);
  color: var(--text-secondary);
}


/* ==========================================================================
   FACTS — the about page's figures. Deliberately plain: these are checkable
   claims, not marketing counters.
   ========================================================================== */

.wf-facts {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-6);
  margin: 0;
}
.wf-fact {
  padding-top: var(--s-4);
  border-top: var(--border-width-strong) solid var(--ink);
}
.wf-fact__label {
  font-family: var(--font-display);
  font-size: var(--t-eyebrow);
  letter-spacing: var(--t-eyebrow-ls);
  text-transform: uppercase;
  color: var(--text-muted);
}
.wf-fact__num {
  margin: var(--s-2) 0;
  font-family: var(--font-display);
  font-size: var(--t-display-l);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--text-primary);
}
.wf-fact__note { font-size: var(--t-body-s); color: var(--text-secondary); }

@media (max-width: 900px) { .wf-facts { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .wf-facts { grid-template-columns: 1fr; gap: var(--s-5); } }


/* ==========================================================================
   FORM — contact
   ========================================================================== */

.wf-form { display: flex; flex-direction: column; gap: var(--s-5); max-width: 34rem; }
.wf-field { display: flex; flex-direction: column; gap: var(--s-2); }
.wf-field__label {
  font-family: var(--font-display);
  font-size: var(--t-body-s);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}
.wf-field__hint { font-size: var(--t-body-s); color: var(--text-muted); }
.wf-input, .wf-textarea, .wf-select {
  width: 100%;
  padding: var(--s-3) var(--s-4);
  font-size: var(--t-input-min);           /* 16px floor — stops iOS zoom */
  color: var(--text-primary);
  background: var(--surface);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-md);
  transition: border-color var(--dur-fast) var(--ease-movement);
}
.wf-input:hover, .wf-textarea:hover, .wf-select:hover { border-color: var(--n-300); }
.wf-textarea { min-height: 9rem; resize: vertical; font-family: inherit; }
.wf-field.is-invalid .wf-input,
.wf-field.is-invalid .wf-textarea { border-color: var(--danger); }
.wf-field__error { font-size: var(--t-body-s); color: var(--danger); }

.wf-contact { display: grid; grid-template-columns: 1.3fr 1fr; gap: var(--s-12); align-items: start; }
.wf-contact__aside {
  padding: var(--s-6);
  background: var(--n-50);
  border-radius: var(--radius-lg);
}
.wf-contact__item + .wf-contact__item { margin-top: var(--s-5); }
/* The email address is the whole paragraph, so it is a standalone target
   rather than a link inside a sentence, and needs the full tap height. */
.wf-contact__item a.u-data { display: inline-flex; align-items: center; min-height: var(--tap-min); }
@media (max-width: 900px) { .wf-contact { grid-template-columns: 1fr; gap: var(--s-8); } }


/* ==========================================================================
   GUIDE — alternating step rows with a real visual for each
   ========================================================================== */

.wf-guide { list-style: none; margin: 0; padding: 0; }
.wf-guide__item {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-8);
  align-items: center;
  padding-block: var(--s-8);
  border-bottom: var(--border-width) solid var(--border-hairline);
}
.wf-guide__item:last-child { border-bottom: 0; }
/* Alternate which side the visual sits on, so the page has a rhythm. */
.wf-guide__item:nth-child(even) .wf-guide__text   { order: 2; }
.wf-guide__item:nth-child(even) .wf-guide__visual { order: 1; }

.wf-guide__title {
  margin-block: var(--s-3);
  font-size: var(--t-display-l);
  line-height: var(--t-display-l-lh);
  letter-spacing: var(--t-display-l-ls);
}
.wf-guide__body { max-width: var(--measure); color: var(--text-secondary); }
.wf-guide__body + .wf-guide__body { margin-top: var(--s-4); }

/* Grid and flex children default to min-width:auto, which refuses to shrink
   below their content's minimum. The guide's mock address bar holds an
   unbreakable URL with a min-content width of ~360px, so on a 375px screen the
   column computed WIDER than its own container and pushed the page 3px sideways.
   Letting the items shrink, and the URL wrap, fixes it at the cause. */
.wf-guide__item > * { min-width: 0; }

@media (max-width: 900px) {
  .wf-guide__item { grid-template-columns: 1fr; gap: var(--s-6); padding-block: var(--s-8); }
  .wf-guide__item:nth-child(even) .wf-guide__text   { order: 0; }
  .wf-guide__item:nth-child(even) .wf-guide__visual { order: 0; }
}

/* Small browser-chrome vignette used in the guide */
.wf-vignette {
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface);
  box-shadow: var(--shadow-md);
}
.wf-vignette__bar {
  display: flex; align-items: center; gap: var(--s-2);
  padding: var(--s-3) var(--s-4);
  background: var(--n-50);
  border-bottom: var(--border-width) solid var(--border-subtle);
  /* Holds a URL, which has no spaces to break at. Without this its min-content
     width sets the floor for the whole guide column. */
  min-width: 0;
  overflow-wrap: anywhere;
}
.wf-vignette__bar > * { min-width: 0; overflow-wrap: anywhere; }
.wf-vignette__dot {
  width: var(--s-3); height: var(--s-3);
  background: var(--n-200); border-radius: var(--radius-pill);
}
.wf-vignette__url {
  flex: 1; min-width: 0;
  margin-inline-start: var(--s-2);
  padding: var(--s-2) var(--s-3);
  background: var(--surface);
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.wf-vignette__body {
  display: flex; align-items: center; justify-content: center;
  min-height: 7rem;
  padding: var(--s-6);
}


/* ==========================================================================
   PROSE — long-form documents: legal pages, guides, FAQ answers.
   Styles raw HTML from the route's pageContent, which is why it targets
   elements rather than classes. Everything is measured for reading, not for
   filling the viewport.
   ========================================================================== */

.wf-doc__head {
  padding-bottom: var(--s-6);
  margin-bottom: var(--s-8);
  border-bottom: var(--border-width) solid var(--border-hairline);
}
.wf-doc__title { margin-bottom: var(--s-3); text-transform: none; }
.wf-doc__meta  { color: var(--text-muted); }

.wf-prose { max-width: var(--measure); color: var(--text-secondary); }
.wf-prose > * + * { margin-top: var(--s-5); }

.wf-prose h2 {
  margin-top: var(--s-12);
  font-size: var(--t-heading-m);
  line-height: var(--t-heading-m-lh);
  color: var(--text-primary);
}
.wf-prose h2:first-child { margin-top: 0; }
.wf-prose h3 {
  margin-top: var(--s-8);
  font-size: var(--t-body-l);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}
.wf-prose h4 { margin-top: var(--s-6); font-size: var(--t-body-m); color: var(--text-primary); }

.wf-prose p  { line-height: var(--t-body-m-lh); }
.wf-prose strong { color: var(--text-primary); font-weight: var(--weight-semibold); }

.wf-prose ul, .wf-prose ol { padding-inline-start: var(--s-6); }
.wf-prose li + li { margin-top: var(--s-2); }
.wf-prose li::marker { color: var(--text-disabled); }

.wf-prose a {
  color: var(--signal-deep);
  /* The privacy policy links out to opt-out pages using the bare address as the
     link text ("policies.google.com/technologies/partner-sites"). No spaces, so
     nowhere to break, and on a 320px screen it ran off the page. */
  overflow-wrap: anywhere;
}

.wf-prose code {
  padding: 0.15em 0.4em;
  background: var(--n-50);
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-sm);
}

.wf-prose blockquote {
  margin-inline: 0;
  padding-inline-start: var(--s-5);
  border-inline-start: var(--border-width-strong) solid var(--signal);
  color: var(--text-primary);
}

/* Tables inside prose scroll within their own box rather than widening the
   page. The legal pages carry wide permission and data-safety tables. */
.wf-prose table {
  display: block;
  overflow-x: auto;
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-body-s);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-md);
}
.wf-prose th, .wf-prose td {
  padding: var(--s-3) var(--s-4);
  text-align: start;
  vertical-align: top;
  border-bottom: var(--border-width) solid var(--border-subtle);
}
.wf-prose th {
  font-family: var(--font-display);
  font-size: var(--t-eyebrow);
  letter-spacing: var(--t-eyebrow-ls);
  text-transform: uppercase;
  color: var(--text-muted);
  background: var(--n-50) !important;   /* overrides inline styles in pageContent */
  white-space: nowrap;
}
.wf-prose tr:last-child td { border-bottom: 0; }

.wf-prose img { border-radius: var(--radius-md); }
.wf-prose hr { height: var(--border-width); background: var(--border-hairline); border: 0; }


/* ==========================================================================
   PLATFORM PAGES
   The platform's own colour tints the eyebrow and one rule — nothing else.
   It never touches the button or the page background, so twelve pages still
   read as one site rather than twelve different ones.
   ========================================================================== */

.wf-hero--platform { border-bottom-color: var(--platform-accent, var(--border-hairline)); }
.wf-hero__eyebrow { color: var(--platform-accent, var(--text-muted)); }

.wf-subtools { border-bottom: var(--border-width) solid var(--border-hairline); }
.wf-subtools .wf-tabs { border-bottom: 0; }
.wf-subtools .wf-tab[aria-current="page"] { border-bottom-color: var(--platform-accent, var(--signal)); }

.wf-platform-intro {
  display: grid;
  grid-template-columns: 1fr 1.4fr;
  gap: var(--s-8);
  align-items: start;
}
.wf-platform-intro__body {
  max-width: var(--measure);
  font-size: var(--t-body-l);
  line-height: var(--t-body-l-lh);
  color: var(--text-secondary);
}
@media (max-width: 900px) {
  .wf-platform-intro { grid-template-columns: 1fr; gap: var(--s-4); }
}


/* ==========================================================================
   DOWNLOADER
   One region, one visible panel at a time. The skeleton mirrors the result
   card's geometry exactly, so arriving data replaces it without moving
   anything on the page.
   ========================================================================== */

.wf-dl { padding-block: var(--s-8); }
.wf-dl:has(.wf-dl__panel.hidden:only-child),
.wf-dl:not(:has(.wf-dl__panel:not(.hidden))) { padding-block: 0; }

.wf-dl__panel {
  max-width: 46rem;
  padding: var(--s-6);
  background: var(--surface);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
/* Result and skeleton span the container — the info + formats sit left, the
   action rail right, so the previously empty right half now works for a
   living. Error/complete stay narrow: a message does not need the width. */
.wf-dl__panel--wide { max-width: none; }

.wf-result-grid {
  display: grid;
  grid-template-columns: 1fr 21rem;
  gap: var(--s-8);
  align-items: start;
}
@media (max-width: 900px) {
  .wf-result-grid { grid-template-columns: 1fr; gap: var(--s-6); }
}

/* ── Action rail ────────────────────────────────────────────────────────── */
.wf-rail {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  padding: var(--s-5);
  background: var(--n-50);
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-lg);
  position: sticky;
  top: calc(var(--header-h) + var(--s-4));
}
@media (max-width: 900px) { .wf-rail { position: static; } }

.wf-rail__label {
  font-family: var(--font-display);
  font-size: var(--t-eyebrow);
  letter-spacing: var(--t-eyebrow-ls);
  text-transform: uppercase;
  color: var(--text-muted);
}
.wf-rail__summary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s-2) var(--s-3);
}
.wf-rail__res {
  font-size: var(--t-display-l);
  font-weight: var(--weight-medium);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--text-primary);
}
.wf-rail__size { color: var(--text-secondary); }
.wf-rail__note { flex-basis: 100%; font-size: var(--t-body-s); color: var(--text-muted); }

.wf-rail__facts {
  margin: 0;
  padding-inline-start: var(--s-5);
  font-size: var(--t-body-s);
  color: var(--text-muted);
}
.wf-rail__facts li + li { margin-top: var(--s-2); }
.wf-rail__facts li::marker { color: var(--signal); }

/* Format rows in selection mode */
.wf-format[aria-checked="true"],
.wf-format.is-selected {
  border-color: var(--signal);
  border-width: var(--border-width-strong);
  background: var(--signal-soft);
}
.wf-format { cursor: pointer; }

/* Group headers splitting the list into Video / Audio, as every established
   downloader lays it out */
.wf-formats__group {
  margin: var(--s-4) 0 var(--s-1);
  font-family: var(--font-display);
  font-size: var(--t-eyebrow);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--t-eyebrow-ls);
  text-transform: uppercase;
  color: var(--text-muted);
}
.wf-formats__group:first-child { margin-top: 0; }

/* Small format chips replacing the sentence-style meta text */
.wf-format__chips { display: inline-flex; flex-wrap: wrap; gap: var(--s-1); }
.wf-chip {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--s-2);
  min-height: 22px;
  font-family: var(--font-mono);
  font-size: var(--t-body-s);
  color: var(--text-secondary);
  background: var(--n-50);
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
.wf-chip--hd    { color: var(--trust); background: var(--trust-soft); border-color: transparent; }
.wf-chip--audio { color: var(--text-muted); }
.wf-chip--best  { color: var(--signal-deep); background: var(--signal-soft); border-color: var(--signal-border); }

/* Per-row download button */
.wf-format__get { justify-self: end; flex-shrink: 0; }
.wf-format__get .wf-btn__icon { width: var(--icon-xs); height: var(--icon-xs); }

/* Rail: success line after a finished download */
.wf-rail__done {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4);
  font-size: var(--t-body-s);
  color: var(--trust);
  background: var(--trust-soft);
  border-radius: var(--radius-md);
}

/* Rail: everything saved this session */
.wf-rail__tray-list { margin: 0; padding: 0; list-style: none; }
.wf-tray__item {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--s-2);
  align-items: center;
  padding-block: var(--s-2);
  border-bottom: var(--border-width) solid var(--border-subtle);
}
.wf-tray__item:last-child { border-bottom: 0; }
.wf-tray__check { display: inline-flex; color: var(--trust); }
.wf-tray__check svg { width: var(--icon-xs); height: var(--icon-xs); }
.wf-tray__name {
  font-size: var(--t-body-s);
  color: var(--text-primary);
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.wf-tray__meta { grid-column: 2; font-size: var(--t-body-s); color: var(--text-muted); }
.wf-dl__panel > * + * { margin-top: var(--s-6); }

/* Error and complete panels bring their own surface via .wf-state */
#dl-error.wf-dl__panel,
#dl-complete.wf-dl__panel { padding: 0; background: none; border: 0; box-shadow: none; }

.wf-dl__subhead {
  font-family: var(--font-display);
  font-size: var(--t-eyebrow);
  letter-spacing: var(--t-eyebrow-ls);
  text-transform: uppercase;
  color: var(--text-muted);
}
.wf-dl__status { color: var(--text-muted); }
.wf-dl__actions { display: flex; flex-wrap: wrap; gap: var(--s-3); }

/* ── Result header ─────────────────────────────────────────────────────── */
.wf-result {
  display: grid;
  grid-template-columns: 15rem 1fr;
  gap: var(--s-5);
  align-items: start;
}
.wf-result__media { position: relative; }

/* aspect-ratio is set here rather than on the img, so the box reserves its
   space before the image loads and the panel never reflows. */
.wf-result__thumb {
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  object-fit: cover;
  background: var(--n-100);
  border-radius: var(--radius-md);
}
.wf-result__thumb--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-disabled);
}
.wf-result__thumb--empty svg { width: var(--icon-xl); height: var(--icon-xl); }

.wf-result__duration {
  position: absolute;
  inset-inline-end: var(--s-2);
  bottom: var(--s-2);
  padding: var(--s-1) var(--s-2);
  font-size: var(--t-body-s);
  color: var(--ground);
  background: var(--backdrop);
  border-radius: var(--radius-sm);
}

.wf-result__meta { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-2); }
.wf-result__title {
  font-family: var(--font-display);
  font-size: var(--t-heading-m);
  line-height: var(--t-heading-m-lh);
  font-weight: var(--weight-semibold);
  /* Exactly two lines, always: clamped so long titles cannot push the panel
     taller, and min-height so short ones still reserve the space. Without the
     min-height the panel's height depends on the title, which is the single
     biggest source of movement when results replace the skeleton. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: calc(2em * var(--t-heading-m-lh));
}
.wf-result__author { color: var(--text-muted); }

.wf-dl__progress { display: block; }

@media (max-width: 767px) {
  .wf-result { grid-template-columns: 1fr; }
  .wf-dl__panel { padding: var(--s-4); }
}

/* ==========================================================================
   LANGUAGE SWITCHER
   Built on <details>/<summary>, so open/close, Esc and focus order come from
   the browser and it works before — or without — JavaScript. Someone who
   cannot read the current language needs this control to work first.
   ========================================================================== */

.wf-header__end {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex-shrink: 0;
}
/* Exactly one element in the row carries the auto margin that eats the free
   space, otherwise two autos split it and the nav drifts to the middle.
   On desktop that is the nav; below 900px the nav is display:none and the
   end group takes over (see the media query near the drawer rules).
   A `.wf-nav + .wf-header__end` rule was doing this before and was wrong:
   adjacent-sibling matching ignores `display`, so it kept applying after the
   nav was hidden and pinned the burger next to the logo. */
.wf-nav { margin-inline-start: auto; }

.wf-lang { position: relative; flex-shrink: 0; }

.wf-lang__trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: var(--tap-min);
  padding: var(--s-2) var(--s-3);
  font-family: var(--font-display);
  font-size: var(--t-body-s);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
  background: none;
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-md);
  cursor: pointer;
  list-style: none;            /* kill the default disclosure triangle */
  user-select: none;
  transition: color var(--dur-fast) var(--ease-movement),
              background var(--dur-fast) var(--ease-movement);
}
/* Safari draws the marker through a pseudo-element instead. */
.wf-lang__trigger::-webkit-details-marker { display: none; }
.wf-lang__trigger::marker { content: ''; }

.wf-lang__trigger:hover { color: var(--text-primary); background: var(--n-50); }
.wf-lang__trigger:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
}
.wf-lang[open] .wf-lang__trigger { color: var(--text-primary); background: var(--n-50); }

.wf-lang__globe { width: var(--icon-sm); height: var(--icon-sm); flex-shrink: 0; }
.wf-lang__caret {
  width: var(--icon-xs); height: var(--icon-xs); flex-shrink: 0;
  transition: transform var(--dur-fast) var(--ease-movement);
}
.wf-lang[open] .wf-lang__caret { transform: rotate(180deg); }

.wf-lang__panel {
  position: absolute;
  top: calc(100% + var(--s-2));
  inset-inline-end: 0;
  z-index: var(--z-dropdown, 50);
  display: grid;
  gap: var(--s-1);
  min-width: 12rem;
  padding: var(--s-2);
  background: var(--ground);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}

.wf-lang__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  min-height: var(--tap-min);
  padding: var(--s-2) var(--s-3);
  font-size: var(--t-body-s);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  text-decoration: none;
  border-radius: var(--radius-sm);
}
.wf-lang__link:hover { color: var(--text-primary); background: var(--n-50); }
.wf-lang__link:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: calc(var(--focus-ring-offset) * -1);
}
.wf-lang__link[aria-current="true"] { color: var(--signal-deep); background: var(--n-50); }
.wf-lang__code {
  font-family: var(--font-mono);
  font-size: var(--t-caption);
  color: var(--text-disabled);
}

/* Inside the mobile drawer the list is always visible — a dropdown within a
   drawer is a needless second layer to open. */
.wf-lang--drawer { width: 100%; }
.wf-lang--drawer .wf-lang__trigger { display: none; }
.wf-lang--drawer .wf-lang__panel {
  position: static;
  min-width: 0;
  padding: 0;
  border: 0;
  box-shadow: none;
  background: none;
  grid-template-columns: repeat(2, 1fr);
}

/* The trigger label is the long part; on narrow screens the globe carries the
   meaning on its own and the header stays on one line. The control itself stays
   visible at every width — burying language switching inside a hamburger means
   someone who cannot read the interface has to guess which icon opens it. */
@media (max-width: 900px) {
  .wf-lang__current { display: none; }
  .wf-lang__caret   { display: none; }
  .wf-lang__trigger { padding: var(--s-2); min-width: var(--tap-min); justify-content: center; }
}

/* ==========================================================================
   RIGHT-TO-LEFT (Arabic)
   Layout mirroring is handled by logical properties throughout; what remains
   is the handful of places where a glyph or a transform has a direction of
   its own and must be flipped explicitly.
   ========================================================================== */

[dir="rtl"] .wf-crumbs__sep { transform: scaleX(-1); }
[dir="rtl"] .wf-step__num,
[dir="rtl"] .wf-slot__chip { direction: ltr; }

/* URLs, file sizes and durations are read left-to-right in every language.
   Without this an Arabic page renders "MB 12.34" and mangles pasted links. */
[dir="rtl"] .u-data,
[dir="rtl"] .wf-slot__input,
[dir="rtl"] .wf-result__meta,
[dir="rtl"] .wf-format__size,
[dir="rtl"] .wf-result__duration,
[dir="rtl"] code,
[dir="rtl"] .wf-table .is-data {
  direction: ltr;
  text-align: start;
}
[dir="rtl"] .wf-lang__code { direction: ltr; }
