/* ═══════════════════════════════════════════════════════════════════════
   Fly Away component kit — v1.6
   The single stylesheet behind natively generated flyaway.ca articles.

   CONTRACT
   - Every class is namespaced `fw-`. Nothing here styles a bare element
     globally, so it can be dropped into any theme without a reset war.
   - Every custom property is namespaced `--fw-`. They sit on :root, which is
     safe precisely BECAUSE they're prefixed — no collision with theme vars.
   - No wrapper element is required. Components are drop-in anywhere.
   - Resets are scoped to `[class*="fw-"]` — component subtrees only — so
     article prose keeps the theme's own paragraph rhythm.
   - No JavaScript. No external requests. No @import.
   - Per-instance colour is set inline: style="--fw-accent:var(--fw-ocean)".

   DARK MODE is opt-in, never automatic. A component must not flip dark on a
   light-only theme. Add `fw-theme-auto` to follow the OS, or `fw-theme-dark`
   to force it. WordPress sets neither.

   Do not hand-edit the copy in wordpress/fly-away-components/assets/ —
   `python3 design/build-kit.py` syncs it from this file.
   ═══════════════════════════════════════════════════════════════════════ */

/* ══ TOKENS ═══════════════════════════════════════════════════════════ */
:root{
  --fw-paper:#F6F5F3; --fw-card:#FFFFFF;
  --fw-ink:#1B1513; --fw-ink-2:#5A5250; --fw-ink-3:#8B8482;
  --fw-sand:#F0E9DE; --fw-rule:#DCD8D2; --fw-rule-2:#EDEAE5;
  --fw-red:#C8102E;    --fw-red-ink:#9C0C24;    --fw-red-wash:#FBEAED;
  --fw-ocean:#0F7D8C;  --fw-ocean-ink:#0A5C68;  --fw-ocean-wash:#E2F0F2;
  --fw-papaya:#E8672C; --fw-papaya-ink:#A8420F; --fw-papaya-wash:#FCEBE1;
  --fw-lagoon:#1E7FC2; --fw-lagoon-ink:#125C8F; --fw-lagoon-wash:#E4F0FA;
  --fw-palm:#2E9E5B;   --fw-palm-ink:#1C6E3D;   --fw-palm-wash:#E4F4EA;
  --fw-coral:#DC3F76;  --fw-coral-ink:#A32351;  --fw-coral-wash:#FCE8EF;
  --fw-violet:#7448C4; --fw-violet-ink:#54318F; --fw-violet-wash:#EFE9FA;
  --fw-gold:#E8A317;   --fw-gold-ink:#96650A;   --fw-gold-wash:#FDF1DA;
  --fw-f-display:"Helvetica Neue",Helvetica,Arial,sans-serif;
  --fw-f-ui:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --fw-f-body:Georgia,"Iowan Old Style","Palatino Linotype",serif;
  --fw-f-data:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,monospace;
  --fw-r:8px; --fw-r-sm:5px; --fw-r-lg:12px;
  --fw-pad:clamp(1rem,3vw,2rem); --fw-maxw:1080px;
  /* Vertical gap between article components. */
  --fw-block-gap:1.75rem;
}

/* Dark palette — applied only where explicitly opted in. */
.fw-theme-dark,:root[data-theme="dark"]{--fw-paper:#141110;--fw-card:#1C1917;--fw-ink:#F2EEE9;--fw-ink-2:#B5ADA8;--fw-ink-3:#7E7671;
    --fw-sand:#2A2320;--fw-rule:#332C29;--fw-rule-2:#262120;
    --fw-red:#F04256;--fw-red-ink:#F0707F;--fw-red-wash:#3A171C;
    --fw-ocean:#3FB3C4;--fw-ocean-ink:#6ACBD8;--fw-ocean-wash:#13303A;
    --fw-papaya:#FF8A50;--fw-papaya-ink:#FFAA7C;--fw-papaya-wash:#372014;
    --fw-lagoon:#57ABEA;--fw-lagoon-ink:#8AC6F3;--fw-lagoon-wash:#152C40;
    --fw-palm:#4FC47F;--fw-palm-ink:#82D9A5;--fw-palm-wash:#152F20;
    --fw-coral:#F0699B;--fw-coral-ink:#F694BA;--fw-coral-wash:#3A1626;
    --fw-violet:#A183E0;--fw-violet-ink:#BCA6EB;--fw-violet-wash:#241B3C;
    --fw-gold:#F5C04A;--fw-gold-ink:#F8D485;--fw-gold-wash:#3A2C12;}
@media (prefers-color-scheme:dark){
  .fw-theme-auto{--fw-paper:#141110;--fw-card:#1C1917;--fw-ink:#F2EEE9;--fw-ink-2:#B5ADA8;--fw-ink-3:#7E7671;
    --fw-sand:#2A2320;--fw-rule:#332C29;--fw-rule-2:#262120;
    --fw-red:#F04256;--fw-red-ink:#F0707F;--fw-red-wash:#3A171C;
    --fw-ocean:#3FB3C4;--fw-ocean-ink:#6ACBD8;--fw-ocean-wash:#13303A;
    --fw-papaya:#FF8A50;--fw-papaya-ink:#FFAA7C;--fw-papaya-wash:#372014;
    --fw-lagoon:#57ABEA;--fw-lagoon-ink:#8AC6F3;--fw-lagoon-wash:#152C40;
    --fw-palm:#4FC47F;--fw-palm-ink:#82D9A5;--fw-palm-wash:#152F20;
    --fw-coral:#F0699B;--fw-coral-ink:#F694BA;--fw-coral-wash:#3A1626;
    --fw-violet:#A183E0;--fw-violet-ink:#BCA6EB;--fw-violet-wash:#241B3C;
    --fw-gold:#F5C04A;--fw-gold-ink:#F8D485;--fw-gold-wash:#3A2C12;}
}

/* ══ SCOPED RESETS ════════════════════════════════════════════════════
   Component subtrees only. `[class*="fw-"]` can't match article prose, so
   the theme keeps owning paragraph margins outside these components. */
[class*="fw-"],[class*="fw-"] *,
[class*="fw-"] *::before,[class*="fw-"] *::after{box-sizing:border-box}
[class*="fw-"] h2,[class*="fw-"] h3,[class*="fw-"] h4,
[class*="fw-"] h5,[class*="fw-"] p{margin:0}
[class*="fw-"] :focus-visible{outline:2px solid var(--fw-red);outline-offset:3px}
/* Pin line-height. Components are laid out against it, and an inherited theme
   value (body{line-height:1.8} and friends) otherwise drifts their heights by
   20%+. Descendants are included because components contain unclassed <div>s
   and <span>s — a bare `div{line-height:…}` rule hits those DIRECTLY, which
   beats anything merely inherited from the component root.
   Specificity is 0,1,0 and this block sits first, so every component rule
   wins on either specificity or source order.
   font-family is deliberately NOT pinned: text inside an article should
   inherit the host theme's face. */
[class*="fw-"],[class*="fw-"] *{line-height:1.65}

/* ══ BLOCK RHYTHM ═════════════════════════════════════════════════════
   Component roots own their own vertical spacing, at a specificity that
   survives the host theme.

   This is the hole a single class leaves. `.fw-cta` is 0,1,0; a theme's
   `.entry-content p` is 0,1,1 and wins, so the CTA lost its top margin
   entirely and collided with the card above it. Blocksy has exactly that
   rule, so this was going to happen in production.

   Doubling the class gives 0,2,0 and beats a theme's descendant selectors
   without reaching for !important. It also fixes the second half of the
   problem: several roots (verdict wrap, comparison wrap, stats, features)
   previously had NO margin, leaving the rhythm entirely up to the host. */
.fw-answer.fw-answer,.fw-trail.fw-trail,.fw-verdict-wrap.fw-verdict-wrap,
.fw-versus.fw-versus,.fw-facts.fw-facts,.fw-pass.fw-pass,
.fw-stats.fw-stats,.fw-personas.fw-personas,.fw-compare-wrap.fw-compare-wrap,
.fw-deck.fw-deck,.fw-features.fw-features,.fw-charts.fw-charts,
.fw-hero.fw-hero,.fw-gal.fw-gal,.fw-callout.fw-callout,
.fw-list.fw-list{margin:0 0 var(--fw-block-gap)}
/* Anything that needs a gap ABOVE it as well. */
.fw-pullquote.fw-pullquote{margin:2rem 0}
.fw-cta.fw-cta{margin:2.25rem 0 0}
.fw-faq.fw-faq{margin:3rem 0 0}

/* ══ 00 · PROSE FURNITURE ═════════════════════════════════
   The base layer the signature components sit between: the answer block,
   lists, callouts, pullquotes, the FAQ and the CTA. Deliberately quieter
   than the plates — this is the connective tissue of an article, and if it
   competes with the components the page stops having a hierarchy. */

/* The answer-first lede. This is the AEO citation target: the passage an
   assistant is most likely to lift, so it's set apart and self-contained
   rather than folded into the opening paragraph. */
.fw-answer{border-left:4px solid var(--fw-red);padding:.15rem 0 .15rem 1.25rem;
  margin:0 0 1.9rem}
.fw-answer .q{font-family:var(--fw-f-ui);font-size:.72rem;font-weight:700;
  letter-spacing:.09em;text-transform:uppercase;color:var(--fw-ink-3);
  margin-bottom:.5rem}
.fw-answer .a{font-size:1.12rem;line-height:1.6;color:var(--fw-ink)}

.fw-list{margin:0 0 1.5rem;padding-left:0;list-style:none}
.fw-list li{position:relative;padding-left:1.5rem;margin-bottom:.5rem;color:var(--fw-ink-2)}
ul.fw-list li::before{content:"";position:absolute;left:.3rem;top:.72em;
  width:.4rem;height:.4rem;border-radius:50%;background:var(--fw-red)}
ol.fw-list{counter-reset:fw}
ol.fw-list li{counter-increment:fw}
ol.fw-list li::before{content:counter(fw);position:absolute;left:0;top:0;
  font-family:var(--fw-f-ui);font-size:.72rem;font-weight:700;color:var(--fw-red)}

/* Tone carries meaning, so the three are visually distinct — but none uses
   brand red, which would read as a Fly Away aside rather than a warning. */
.fw-callout{border-radius:var(--fw-r);padding:1.05rem 1.25rem;margin:0 0 1.6rem;
  border-left:4px solid var(--fw-tone,var(--fw-lagoon));
  background:color-mix(in srgb,var(--fw-tone,var(--fw-lagoon)) 8%,transparent)}
.fw-callout.note{--fw-tone:var(--fw-lagoon)}
.fw-callout.tip{--fw-tone:var(--fw-palm)}
.fw-callout.warning{--fw-tone:var(--fw-gold)}
.fw-callout h4{font-family:var(--fw-f-ui);font-size:.74rem;font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;margin-bottom:.45rem;
  color:var(--fw-tone-ink,var(--fw-lagoon-ink))}
.fw-callout.note h4{--fw-tone-ink:var(--fw-lagoon-ink)}
.fw-callout.tip h4{--fw-tone-ink:var(--fw-palm-ink)}
.fw-callout.warning h4{--fw-tone-ink:var(--fw-gold-ink)}
.fw-callout p{color:var(--fw-ink-2);font-size:.96rem}
.fw-callout p+p{margin-top:.6rem}

.fw-pullquote{margin:2rem 0;padding:0 0 0 1.5rem;border-left:3px solid var(--fw-red)}
.fw-pullquote p{font-family:var(--fw-f-display);font-size:clamp(1.2rem,2.6vw,1.6rem);
  font-weight:700;letter-spacing:-.02em;line-height:1.3;color:var(--fw-ink)}
.fw-pullquote cite{display:block;margin-top:.6rem;font-style:normal;
  font-family:var(--fw-f-ui);font-size:.74rem;letter-spacing:.06em;
  text-transform:uppercase;color:var(--fw-ink-3)}

/* Native <details> — an accordion with no JavaScript, and one that stays
   open to Ctrl+F and to crawlers. */
.fw-faq{margin:2.5rem 0 0;border-top:2px solid var(--fw-ink);padding-top:1.1rem}
.fw-faq h2{font-size:.95rem;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;margin-bottom:.9rem}
.fw-faq-item{border-bottom:1px solid var(--fw-rule)}
.fw-faq-item summary{cursor:pointer;list-style:none;padding:.85rem 2rem .85rem 0;
  position:relative;font-family:var(--fw-f-display);font-size:1.02rem;font-weight:700;
  letter-spacing:-.01em;color:var(--fw-ink)}
.fw-faq-item summary::-webkit-details-marker{display:none}
.fw-faq-item summary::after{content:"";position:absolute;right:.35rem;top:1.25rem;
  width:.55rem;height:.55rem;border-right:2px solid var(--fw-red);
  border-bottom:2px solid var(--fw-red);transform:rotate(45deg);
  transition:transform .2s ease}
.fw-faq-item[open] summary::after{transform:rotate(225deg)}
.fw-faq-item p{color:var(--fw-ink-2);font-size:.96rem;padding-bottom:.95rem}
.fw-faq-item p+p{padding-bottom:0;margin-bottom:.95rem}
@media (prefers-reduced-motion:reduce){.fw-faq-item summary::after{transition:none}}

.fw-cta{margin:2rem 0 0}

/* ══ OPERATOR CHIPS ═══════════════════════════════════════ */
/* Code tile only — no name label. The airline name stays in the DOM as
   visually-hidden text so screen readers and extractors still get it. */
.fw-vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0}
.fw-op{display:inline-flex;vertical-align:middle}
.fw-op i{font-style:normal;display:grid;place-items:center;width:2.15rem;height:1.65rem;
  border-radius:var(--fw-r-sm);font-family:var(--fw-f-ui);font-size:.64rem;font-weight:700;
  letter-spacing:.04em;color:#fff}
.fw-op-ac i{background:#D52B1E} .fw-op-wj i{background:#00A99D} .fw-op-pd i{background:#0A2342}
.fw-op-fl i{background:#97D700;color:#243300} .fw-op-ts i{background:#0057B8} .fw-op-sw i{background:#F58220}

/* ══ 01 · FLIGHT-TRAIL TIMELINE ═══════════════════════════
   Curve is back. The reveal is a clip-path WIPE, not stroke-dash:
   stroke-dash + pathLength is broken by non-scaling-stroke (the dash
   gets measured in screen px → the banded line you saw). A wipe is
   independent of path length and works on any curve. */
.fw-trail{position:relative;margin:0;padding:0;list-style:none;
  view-timeline-name:--trail;view-timeline-axis:block}
.fw-trail-rail{position:absolute;top:.7rem;bottom:6.09rem;left:50%;transform:translateX(-50%);
  width:6rem;pointer-events:none}
.fw-trail-rail svg{width:100%;height:100%;display:block}
.fw-trail-rail path{fill:none;stroke-width:2;stroke-linecap:round;stroke-dasharray:3 7;
  vector-effect:non-scaling-stroke}
.fw-trail-rail .base{stroke:var(--fw-rule)}
.fw-trail-prog{position:absolute;inset:0;clip-path:inset(0 0 100% 0)}
.fw-trail-prog path{stroke:var(--fw-red)}
.fw-trail li{position:relative;padding:0 0 2.25rem}
.fw-trail li:last-child{padding-bottom:0}
.fw-trail .node{position:absolute;top:.32rem;width:.8rem;height:.8rem;border-radius:50%;
  background:var(--fw-paper);border:2px solid var(--fw-red);z-index:2}
.fw-trail .when{font-family:var(--fw-f-data);font-size:.66rem;letter-spacing:.11em;text-transform:uppercase;
  color:var(--fw-red);display:block;margin-bottom:.2rem}
.fw-trail h4{font-size:1.05rem;font-weight:700;letter-spacing:-.015em;margin-bottom:.2rem}
.fw-trail p{color:var(--fw-ink-2);font-size:.94rem}
/* terminus: a larger ring that fills on arrival. No plane. */
.fw-trail .arrive{position:absolute;top:-.5rem;width:2.3rem;height:2.3rem;border-radius:50%;
  z-index:3;background:var(--fw-paper);border:3px solid var(--fw-red);box-shadow:0 0 0 5px var(--fw-paper)}
.fw-trail .arrive::after{content:"";position:absolute;inset:.28rem;border-radius:50%;
  background:var(--fw-red);transform:scale(0);transition:transform .3s ease}
@supports (animation-timeline:--trail){
  @media (prefers-reduced-motion:no-preference){
    .fw-trail-prog{animation:wipe linear both;animation-timeline:--trail;
      animation-range:cover 12% cover 82%}
    @keyframes wipe{to{clip-path:inset(0 0 0% 0)}}
    .fw-trail .arrive::after{animation:fill ease both;animation-timeline:--trail;
      animation-range:cover 78% cover 86%}
    @keyframes fill{to{transform:scale(1)}}
  }
}
@supports not (animation-timeline:--trail){
  .fw-trail-prog{clip-path:inset(0 0 0% 0)}
  .fw-trail .arrive::after{transform:scale(1)}
}
@media (min-width:690px){
  .fw-trail li{width:calc(50% - 3rem);min-height:6.75rem}
  .fw-trail li:nth-child(odd){margin-left:auto}
  .fw-trail li:nth-child(odd) .node{left:-3.4rem}
  .fw-trail li:nth-child(odd) .arrive{left:-4.15rem}
  .fw-trail li:nth-child(even){margin-right:auto;text-align:right}
  .fw-trail li:nth-child(even) .node{right:-3.4rem}
  .fw-trail li:nth-child(even) .arrive{right:-4.15rem}
}
@media (max-width:689px){
  .fw-trail{padding-left:3.4rem}
  .fw-trail-rail{left:0;transform:none;width:3.4rem;bottom:5.59rem}
  .fw-trail li{padding-bottom:1.7rem}
  .fw-trail .node{left:-2.1rem}
  .fw-trail .arrive{left:-2.85rem}
  .fw-trail h4{font-size:.98rem}
}

/* ══ 02 · VERDICT SPLIT ═══════════════════════════════════ */
.fw-verdict-wrap{position:relative}
.fw-verdict{display:grid;grid-template-columns:1fr 1fr;gap:1.5rem;align-items:stretch}
.fw-vcard{background:var(--fw-card);border:1px solid var(--fw-rule);border-radius:var(--fw-r-lg);
  display:flex;flex-direction:column;overflow:hidden}
.fw-vcard .bar{height:.45rem;flex:none}
/* Accent-driven, not hardcoded: the model lets the generator choose the pair,
   so the renderer sets --fw-accent/-ink/-wash inline per card. The ocean /
   papaya fallbacks keep hand-written markup working. */
.fw-vcard .bar{background:var(--fw-accent,var(--fw-ocean))}
.fw-vcard.b .bar{background:var(--fw-accent,var(--fw-papaya))}
.fw-vcard .inner{padding:1.5rem;display:flex;flex-direction:column;flex:1}
.fw-vcard .kicker{font-family:var(--fw-f-ui);font-size:.7rem;font-weight:600;letter-spacing:.09em;
  text-transform:uppercase;align-self:flex-start;border-radius:999px;padding:.22rem .7rem;margin-bottom:.75rem}
.fw-vcard .kicker{background:var(--fw-accent-wash,var(--fw-ocean-wash));
  color:var(--fw-accent-ink,var(--fw-ocean-ink))}
.fw-vcard.b .kicker{background:var(--fw-accent-wash,var(--fw-papaya-wash));
  color:var(--fw-accent-ink,var(--fw-papaya-ink))}
.fw-vcard h3{font-size:1.35rem;font-weight:700;letter-spacing:-.02em;line-height:1.15;margin-bottom:.9rem}
.fw-vcard ul{list-style:none;margin:0 0 1.2rem;padding:0;font-size:.94rem;color:var(--fw-ink-2);flex:1}
.fw-vcard li{padding-left:1.25rem;position:relative;margin-bottom:.4rem}
.fw-vcard li::before{content:"";position:absolute;left:0;top:.55em;width:.5rem;height:.5rem;
  border-radius:50%;border:1.5px solid currentColor}
.fw-vcard li::before{color:var(--fw-accent,var(--fw-ocean))}
.fw-vcard.b li::before{color:var(--fw-accent,var(--fw-papaya))}
.fw-vcard .choose{border-top:1px dashed var(--fw-rule);padding-top:.9rem;font-size:.93rem;color:var(--fw-ink)}
.fw-vcard .choose b{font-family:var(--fw-f-ui);font-size:.68rem;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;display:block;margin-bottom:.3rem}
.fw-vcard .choose b{color:var(--fw-accent-ink,var(--fw-ocean-ink))}
.fw-vcard.b .choose b{color:var(--fw-accent-ink,var(--fw-papaya-ink))}
/* Desktop: absolutely centred — safe because the cards stretch to equal height.
   Mobile: it becomes a real grid ITEM between the two cards. top:50% of the
   wrapper is NOT the gap once the cards have different heights — that was the
   misplacement. */
.fw-vs{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:3;
  background:var(--fw-paper);width:2.5rem;height:2.5rem;border-radius:50%;border:1px solid var(--fw-rule);
  display:grid;place-items:center;font-family:var(--fw-f-ui);font-size:.66rem;font-weight:700;
  letter-spacing:.06em;color:var(--fw-ink-3)}
@media (max-width:689px){
  .fw-verdict{grid-template-columns:1fr;gap:.5rem}
  .fw-vcard .inner{padding:1.25rem}
  .fw-vs{position:relative;top:auto;left:auto;transform:none;justify-self:center;
    margin:-.35rem 0;box-shadow:0 0 0 5px var(--fw-paper)}
}

/* ══ 02b · VERSUS DETAIL ══════════════════════════════════
   One dimension, both options, a paragraph each — repeated down a comparison
   article. Distinct from the verdict split, which is the single closing
   recommendation; this is the body.

   Card carries a vivid accent bar and a filled label pill; the card fill
   itself stays neutral so the colour does the work without the page turning
   into a paint chart. */
.fw-versus{display:grid;grid-template-columns:1fr 1fr;gap:.9rem;margin:0 0 1.6rem}
.fw-versus .dim{grid-column:1/-1;font-family:var(--fw-f-display);font-size:1.05rem;
  font-weight:700;letter-spacing:-.015em;color:var(--fw-ink);margin-bottom:-.1rem}
/* A claim that covers BOTH options, above the pair rather than inside whichever
   card comes first. Without this slot the model had nowhere to put "neither is
   reliably cheaper" and said it twice, once per side. Spans the grid like the
   dimension title does, and stays quieter than either card so it reads as the
   setup rather than a third option. */
.fw-versus .shared{grid-column:1/-1;font-size:.94rem;color:var(--fw-ink-2);
  margin:-.15rem 0 .2rem;max-width:62ch}

/* Neutral tint rather than a fixed grey: a translucent ink wash sits correctly
   on any host background and inverts for free in dark mode. */
.fw-versus .side{background:color-mix(in srgb,var(--fw-ink) 4%,transparent);
  border-left:5px solid var(--fw-accent,var(--fw-ocean));
  border-radius:0 var(--fw-r) var(--fw-r) 0;padding:1.05rem 1.3rem 1.15rem;min-width:0}
/* Pill uses the accent's INK shade, not the accent itself. White on the raw
   accent fails 4.5:1 for half the palette at this size (gold, palm, papaya,
   coral, lagoon all fall short); the ink shades are the palette's designated
   accessible variants. The bar keeps the vivid tone. */
.fw-versus .lbl{display:inline-flex;align-items:center;gap:.42rem;
  background:var(--fw-accent-ink,var(--fw-ocean-ink));color:#fff;
  font-family:var(--fw-f-ui);font-size:.7rem;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;padding:.42rem .9rem;border-radius:999px;margin-bottom:.75rem}
/* The glyph sits in a white disc and takes the pill's own colour, which reads
   as a badge rather than a second word. `currentColor` on the <use> means the
   disc sets the glyph colour, so it tracks the accent with no extra variable.
   Fixed square with centred content: the icons have different intrinsic
   proportions and left-aligning them made the pills look unevenly padded. */
.fw-versus .lbl svg{width:1.15rem;height:1.15rem;flex:none;
  background:#fff;border-radius:50%;padding:.22rem;
  color:var(--fw-accent-ink,var(--fw-ocean-ink));
  box-sizing:border-box;overflow:visible;
  /* Pulled left with a negative margin rather than by trimming the pill's
     padding, so a label with no icon keeps its .9rem inset and does not end up
     with text jammed against the curve. .9 - .48 leaves .42rem, the same as
     the vertical padding, which puts the disc equidistant from top, bottom and
     the rounded cap instead of floating in the middle of the left inset. */
  margin-left:-.48rem}
.fw-versus p{font-size:.96rem;color:var(--fw-ink-2)}
@media (max-width:689px){
  .fw-versus{grid-template-columns:1fr;gap:.7rem}
  .fw-versus .side{padding:.9rem 1.1rem 1rem}
}

/* ══ 03 · FACTS RIBBON ════════════════════════════════════ */
.fw-figure{position:relative;padding-bottom:3rem;margin:0}
.fw-slot{aspect-ratio:21/9;position:relative;border-radius:var(--fw-r-lg);overflow:hidden;
  background:linear-gradient(155deg,#12303A 0%,#1D4E5C 45%,#3A6E70 74%,#6B7F6A 100%)}
.fw-slot::after{content:"IMAGE SLOT · 21:9";position:absolute;right:.8rem;top:.7rem;
  font-family:var(--fw-f-data);font-size:.58rem;letter-spacing:.12em;color:rgba(255,255,255,.5)}
.fw-ribbon{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--fw-rule);
  border:1px solid var(--fw-rule);border-radius:var(--fw-r);overflow:hidden;
  position:absolute;left:1.75rem;right:1.75rem;bottom:0}
.fw-ribbon>div{background:var(--fw-card);padding:1rem 1.15rem}
.fw-ribbon dt{font-family:var(--fw-f-ui);font-size:.7rem;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;color:var(--fw-ink-3);margin-bottom:.3rem}
.fw-ribbon dd{margin:0;font-family:var(--fw-f-display);font-weight:700;font-size:1.3rem;
  letter-spacing:-.02em;color:var(--fw-red)}
.fw-ribbon dd em{font-style:normal;color:var(--fw-ink-3);font-family:var(--fw-f-ui);font-size:.82rem;
  font-weight:600;margin-left:.2rem}
@media (max-width:999px){.fw-ribbon{left:1rem;right:1rem}}
@media (max-width:689px){
  .fw-figure{padding-bottom:0}
  .fw-ribbon{position:static;grid-template-columns:repeat(2,1fr);margin-top:-1px;
    border-radius:0 0 var(--fw-r) var(--fw-r)}
  .fw-slot{aspect-ratio:16/10;border-radius:var(--fw-r) var(--fw-r) 0 0}
  .fw-ribbon dd{font-size:1.15rem}
}

/* ══ 04 · BOARDING PASS — banded layout, Wallet-ish ═══════ */
/* --fw-stub drives both the track and the notch position, so they can't drift. */
.fw-pass{--fw-stub:14rem;background:var(--fw-card);border:1px solid var(--fw-rule);border-radius:var(--fw-r-lg);
  overflow:hidden;display:grid;grid-template-columns:1fr var(--fw-stub);position:relative}
.fw-pass-main{min-width:0}
/* dark header band, like the reference's black panel */
.fw-pass-hd{background:var(--fw-ink);color:#fff;display:flex;align-items:center;
  justify-content:space-between;gap:1rem;padding:.85rem 1.5rem}
.fw-pass-brand{display:flex;align-items:center;gap:.55rem;font-family:var(--fw-f-display);
  font-weight:700;font-size:.74rem;letter-spacing:.16em;text-transform:uppercase}
.fw-pass-brand svg{width:1.3rem;height:1.3rem;color:var(--fw-red);flex:none}
.fw-pass-hd .doc{font-family:var(--fw-f-ui);font-size:.64rem;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:rgba(255,255,255,.62)}
/* route band */
.fw-pass-route{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:1.25rem;
  padding:1.5rem;border-bottom:1px solid var(--fw-rule-2)}
.fw-port .code{font-family:var(--fw-f-display);font-size:clamp(2.1rem,6vw,3.1rem);font-weight:700;
  line-height:.95;display:block;letter-spacing:-.03em}
.fw-port .city{font-family:var(--fw-f-ui);font-size:.7rem;font-weight:500;color:var(--fw-ink-3);
  display:block;margin-top:.3rem}
.fw-port.to{text-align:right}
.fw-hop{display:flex;flex-direction:column;align-items:center;gap:.3rem;color:var(--fw-red)}
.fw-hop svg{width:1.5rem;height:1.5rem}
.fw-hop span{font-family:var(--fw-f-ui);font-size:.62rem;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--fw-ink-3);white-space:nowrap}
.fw-hop .ln{width:100%;min-width:3.5rem;border-top:2px dotted var(--fw-red);opacity:.5}
/* field grid */
.fw-pass-fields{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--fw-rule-2)}
.fw-pass-fields>div{background:var(--fw-card);padding:.85rem 1.5rem}
.fw-pass-fields dt{font-family:var(--fw-f-ui);font-size:.62rem;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--fw-ink-3);margin-bottom:.2rem}
.fw-pass-fields dd{margin:0;font-family:var(--fw-f-display);font-weight:700;font-size:1rem}
.fw-pass-ops{display:flex;flex-wrap:wrap;gap:.4rem;padding:1rem 1.5rem 1.15rem;
  border-top:1px solid var(--fw-rule-2)}
/* stub — carries the OPERATING AIRLINE's brand colour, set per instance
   via --fw-op. Gives the carrier a featured position instead of a sand slab. */
.fw-pass-stub{border-left:2px dashed var(--fw-rule);background:var(--fw-op,var(--fw-ink));color:#fff;
  padding:1.15rem 1.15rem .9rem;display:flex;flex-direction:column;gap:.7rem;position:relative}
.fw-pass-stub .tag{font-family:var(--fw-f-ui);font-size:.58rem;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:rgba(255,255,255,.6)}
.fw-pass-stub .carrier{display:flex;align-items:center;gap:.55rem}
/* white tile with standard ink — reads as a logo plate, and it's where a real
   supplied airline mark would drop in */
.fw-pass-stub .carrier .mono{width:2.1rem;height:2.1rem;border-radius:var(--fw-r-sm);flex:none;
  background:#fff;color:var(--fw-ink);display:grid;place-items:center;
  font-family:var(--fw-f-ui);font-size:.72rem;font-weight:700;letter-spacing:.02em}
.fw-pass-stub .carrier .nm{font-family:var(--fw-f-display);font-size:.95rem;font-weight:700;
  letter-spacing:-.01em;line-height:1.15}
.fw-pass-stub .carrier .nm small{display:block;font-family:var(--fw-f-ui);font-size:.6rem;
  font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:rgba(255,255,255,.62)}
.fw-pass-stub .sroute{font-family:var(--fw-f-display);font-size:1.4rem;font-weight:700;
  letter-spacing:-.02em;line-height:1;padding-top:.55rem;border-top:1px solid rgba(255,255,255,.22)}
.fw-pass-stub .row{display:flex;justify-content:space-between;gap:.6rem;font-family:var(--fw-f-ui);
  font-size:.7rem}
.fw-pass-stub .row span{color:rgba(255,255,255,.62);font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;font-size:.62rem}
.fw-pass-stub .row b{font-weight:700}
.fw-pass-stub .legal{margin-top:auto;padding-top:.7rem;border-top:1px solid rgba(255,255,255,.18);
  font-family:var(--fw-f-ui);font-size:.54rem;line-height:1.45;color:rgba(255,255,255,.55)}
.fw-notch{position:absolute;width:1.1rem;height:1.1rem;border-radius:50%;background:var(--fw-paper);
  right:var(--fw-stub);transform:translateX(50%);z-index:2}
.fw-notch.t{top:-.55rem} .fw-notch.b{bottom:-.55rem}
@media (max-width:999px){
  .fw-pass-fields{grid-template-columns:repeat(2,1fr)}
  /* Fluid stub: a fixed 14rem keeps its pixels but grows as a SHARE of the card
     as the card shrinks (29% → 34% by 700px). Percentage-based holds the share
     steady; the rem floor stops the carrier tile and route from cramping. */
  .fw-pass{--fw-stub:clamp(10.5rem,28%,14rem)}
}
@media (max-width:689px){
  .fw-pass{grid-template-columns:1fr}
  .fw-pass-hd{padding:.75rem 1.1rem}
  .fw-pass-route{padding:1.15rem;gap:.75rem}
  .fw-pass-fields>div{padding:.7rem 1.1rem}
  .fw-pass-ops{padding:.85rem 1.1rem 1rem}
  /* Stub becomes a full-width band. Two EQUAL columns — an `auto` track sizes
     to its widest item, so the disclaimer would inflate the left column and
     starve the right one. minmax(0,1fr) also stops a long value blowing the
     track out past the card. Only the two field rows pair up; everything
     wide spans the full width. */
  .fw-pass-stub{border-left:0;border-top:2px dashed var(--fw-rule);
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    gap:.6rem 1rem;align-items:start;padding:1rem 1.1rem}
  .fw-pass-stub .tag,
  .fw-pass-stub .carrier,
  .fw-pass-stub .sroute,
  .fw-pass-stub .legal{grid-column:1/-1}
  .fw-pass-stub .legal{margin-top:.25rem}
  .fw-notch{display:none}
}

/* ══ 05 · BIG-NUMBER STATS ════════════════════════════════ */
.fw-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem}
/* Dashed frame is SVG, not `border-style:dashed` — CSS gives no control over
   dash length, so a CSS border can't match the persona picker's 5/5 rhythm.
   No CSS border at all: the frame must trace the border box, or the card's
   background paints a sliver of white outside the dashes. */
.fw-stat{position:relative;background:var(--fw-card);border:0;
  border-radius:var(--fw-r-lg);padding:1.6rem 1.5rem}
.fw-stat .fr{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}
.fw-stat .fr rect{fill:none;stroke:var(--fw-red);stroke-width:1.5;rx:12;ry:12;x:.75;y:.75;
  width:calc(100% - 1.5px);height:calc(100% - 1.5px);stroke-dasharray:5 5}
.fw-stat .n{font-family:var(--fw-f-display);font-size:clamp(3.6rem,9vw,5.4rem);font-weight:700;
  letter-spacing:-.055em;line-height:.85;color:var(--fw-red);font-variant-numeric:tabular-nums;display:block}
.fw-stat .n sup{font-size:.38em;vertical-align:super;letter-spacing:0}
.fw-stat .unit{font-family:var(--fw-f-ui);font-size:.72rem;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--fw-ink-3);display:block;margin:.85rem 0 .6rem;
  border-top:2px solid var(--fw-red);padding-top:.6rem;width:2.75rem}
.fw-stat p{font-size:.93rem;color:var(--fw-ink-2)}
@media (max-width:689px){.fw-stats{grid-template-columns:1fr}}

/* ══ 06 · PERSONA PICKER ══════════════════════════════════ */
.fw-personas{display:grid;grid-template-columns:repeat(3,1fr);gap:1.25rem}
/* No CSS border — the SVG frame traces the border box, so the card background
   can't paint outside the dashes. */
.fw-persona{position:relative;background:var(--fw-card);border:0;
  border-radius:var(--fw-r-lg);padding:calc(1.4rem + 1px);display:flex;flex-direction:column;
  text-decoration:none;color:inherit}
.fw-persona .fr{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}
.fw-persona .fr rect{fill:none;stroke-width:1.5;rx:12;ry:12;x:.75;y:.75;
  width:calc(100% - 1.5px);height:calc(100% - 1.5px)}
.fw-persona .fr .base{stroke:var(--fw-rule);stroke-dasharray:5 5}
.fw-persona .fr .draw{stroke:var(--fw-accent,var(--fw-ocean));stroke-dasharray:100;
  stroke-dashoffset:100;transition:stroke-dashoffset .55s ease}
a.fw-persona:hover .fr .draw{stroke-dashoffset:0}
@media (prefers-reduced-motion:reduce){.fw-persona .fr .draw{transition:none}}
.fw-persona .size{font-family:var(--fw-f-ui);font-size:.7rem;font-weight:600;letter-spacing:.03em;
  align-self:flex-start;padding:.3rem .8rem;border-radius:999px;margin-bottom:1rem;
  color:var(--fw-accent-ink,var(--fw-ocean-ink));background:var(--fw-accent-wash,var(--fw-ocean-wash))}
.fw-persona h4{font-size:1.1rem;font-weight:700;letter-spacing:-.015em;margin-bottom:.4rem}
.fw-persona p{font-size:.93rem;color:var(--fw-ink-2);flex:1}
.fw-persona .fit{margin-top:1rem;padding-top:.85rem;border-top:1px dashed var(--fw-rule);
  font-family:var(--fw-f-ui);font-size:.82rem;color:var(--fw-ink-3);line-height:1.5;
  display:flex;align-items:center;justify-content:space-between;gap:.75rem}
.fw-persona .fit svg{width:1rem;height:1rem;flex:none;color:var(--fw-accent,var(--fw-ocean));transition:transform .2s}
a.fw-persona:hover .fit svg{transform:translateX(3px)}
@media (max-width:999px){.fw-personas{grid-template-columns:repeat(2,1fr)}}
@media (max-width:689px){.fw-personas{grid-template-columns:1fr}}

/* ══ 07 · COMPARISON — table on desktop, SWIPE DECK on mobile ═ */
.fw-compare{width:100%;border-collapse:separate;border-spacing:0;font-size:.94rem}
.fw-compare caption{text-align:left;font-family:var(--fw-f-ui);font-size:.76rem;font-weight:600;
  letter-spacing:.04em;text-transform:uppercase;color:var(--fw-ink-3);padding-bottom:.7rem}
.fw-compare th,.fw-compare td{padding:.78rem 1rem;text-align:left;vertical-align:top}
.fw-compare thead th:first-child{background:none;border:0;padding:0}
.fw-compare thead th:nth-child(2),.fw-compare thead th:nth-child(3){
  font-family:var(--fw-f-ui);font-size:.8rem;font-weight:700;letter-spacing:.02em;
  border-radius:var(--fw-r) var(--fw-r) 0 0;white-space:nowrap}
.fw-compare thead th:nth-child(2){background:var(--fw-accent-wash,var(--fw-ocean-wash));
  color:var(--fw-accent-ink,var(--fw-ocean-ink));
  box-shadow:inset 0 4px 0 var(--fw-accent,var(--fw-ocean))}
.fw-compare thead th:nth-child(3){background:var(--fw-accent-wash,var(--fw-papaya-wash));
  color:var(--fw-accent-ink,var(--fw-papaya-ink));
  box-shadow:inset 0 4px 0 var(--fw-accent,var(--fw-papaya))}
.fw-compare tbody th{font-family:var(--fw-f-ui);font-size:.82rem;font-weight:600;color:var(--fw-ink);
  width:30%;border-bottom:1px solid var(--fw-rule-2)}
.fw-compare tbody td{color:var(--fw-ink-2);background:var(--fw-card);border-bottom:1px solid var(--fw-rule-2)}
.fw-compare tbody tr:first-child td{border-top:1px solid var(--fw-rule-2)}
.fw-compare tbody tr:last-child td:nth-child(2){border-radius:0 0 0 var(--fw-r)}
.fw-compare tbody tr:last-child td:nth-child(3){border-radius:0 0 var(--fw-r) 0}
/* swipe deck: one attribute per card, snap-scrolled. No JS. */
.fw-deck{display:none}
.fw-deck-track{display:flex;gap:.85rem;overflow-x:auto;scroll-snap-type:x mandatory;
  -webkit-overflow-scrolling:touch;padding-bottom:.6rem;scrollbar-width:none;
  scroll-timeline-name:--deck;scroll-timeline-axis:inline}
.fw-deck-track::-webkit-scrollbar{display:none}
.fw-dcard{flex:0 0 86%;scroll-snap-align:center;background:var(--fw-card);border:1px solid var(--fw-rule);
  border-radius:var(--fw-r-lg);overflow:hidden}
.fw-dcard h4{font-family:var(--fw-f-ui);font-size:.82rem;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--fw-ink-3);padding:.8rem 1rem;border-bottom:1px solid var(--fw-rule-2)}
.fw-dcard .pair{display:grid;grid-template-columns:1fr 1fr}
.fw-dcard .side{padding:.9rem 1rem 1rem}
.fw-dcard .side:first-child{border-right:1px solid var(--fw-rule-2)}
.fw-dcard .lbl{font-family:var(--fw-f-ui);font-size:.64rem;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;display:block;margin-bottom:.3rem}
.fw-dcard .side.a .lbl{color:var(--fw-accent-ink,var(--fw-ocean-ink))}
.fw-dcard .side.b .lbl{color:var(--fw-accent-ink,var(--fw-papaya-ink))}
.fw-dcard .side.a{box-shadow:inset 0 3px 0 var(--fw-accent,var(--fw-ocean))}
.fw-dcard .side.b{box-shadow:inset 0 3px 0 var(--fw-accent,var(--fw-papaya))}
.fw-dcard .val{font-size:.92rem;color:var(--fw-ink)}
/* swipe affordance: chevrons + a pill that tracks the scroller (scroll-timeline) */
.fw-deck-hint{display:flex;align-items:center;justify-content:center;gap:.6rem;margin-top:.35rem;
  font-family:var(--fw-f-ui);font-size:.66rem;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--fw-ink-3)}
/* Brand red is reserved. Inside a comparison an accent MEANS "this option",
   so red here would read as a third option — or as the brand taking a side.
   The swipe affordance is chrome, so it stays neutral. */
.fw-deck-hint svg{width:.85rem;height:.85rem;color:var(--fw-ink-3)}
.fw-deck-hint .rev{transform:scaleX(-1)}
.fw-deck-bar{max-width:7rem;flex:1;height:.28rem;border-radius:999px;background:var(--fw-rule-2);
  overflow:hidden}
.fw-deck-bar i{display:block;height:100%;width:calc(100% / 6);border-radius:999px;
  background:var(--fw-ink-2);transform:translateX(0)}
/* A named scroll-timeline is only visible to the scroller's descendants unless a
   common ancestor hoists it with timeline-scope. Without that the animation never
   attached and `both` fill parked the pill at its end state. */
@supports (timeline-scope:--deck){
  @media (prefers-reduced-motion:no-preference){
    .fw-deck{timeline-scope:--deck}
    .fw-deck-bar i{animation:deckpill linear both;animation-timeline:--deck}
    @keyframes deckpill{from{transform:translateX(0)}to{transform:translateX(500%)}}
  }
}
@media (max-width:689px){
  .fw-compare-wrap{display:none}
  .fw-deck{display:block}
}

/* ══ 08 · BUTTONS ═════════════════════════════════════════ */
.fw-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  font-family:var(--fw-f-ui);font-size:.88rem;font-weight:600;letter-spacing:.01em;
  padding:.55rem 1.15rem;border-radius:var(--fw-r);border:0;cursor:pointer;text-decoration:none;
  background:none;color:var(--fw-ink);transition:background .18s,color .18s,border-color .18s}
.fw-btn .ico{width:1.05rem;height:1.05rem;flex:none}
.fw-btn.lg{font-size:.95rem;padding:.72rem 1.5rem}
.fw-btn.sm{font-size:.8rem;padding:.42rem .85rem}
.fw-btn.solid{background:var(--fw-red);color:#fff}
.fw-btn.solid:hover{background:var(--fw-red-ink)}
.fw-btn.ghost{border:1.5px solid var(--fw-rule)}
.fw-btn.ghost:hover{border-color:var(--fw-red);color:var(--fw-red)}
.fw-btn.quiet{color:var(--fw-ink-2);padding-left:.35rem;padding-right:.35rem}
.fw-btn.quiet:hover{color:var(--fw-red)}
.fw-btn.icon-only{padding:.55rem;gap:0}
.fw-trace-fr{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}
.fw-trace-fr rect{fill:none;stroke-width:1.5;rx:8;ry:8;x:.75;y:.75;
  width:calc(100% - 1.5px);height:calc(100% - 1.5px)}
.fw-trace-fr .base{stroke:var(--fw-rule);stroke-dasharray:5 5}
/* Dashed at rest → solid on hover: the outline "commits". pathLength=100 makes
   the dash length geometry-independent, so one dash of 100 covers the whole
   perimeter and dashoffset slides it into view. This is why the drawn line
   can't itself be dashed — dasharray is the reveal mechanism, not decoration. */
.fw-trace-fr .draw{stroke:var(--fw-red);stroke-dasharray:100;stroke-dashoffset:100;
  transition:stroke-dashoffset .55s ease}
.fw-btn.trace:hover{color:var(--fw-red)}
.fw-btn.trace:hover .draw{stroke-dashoffset:0}
@media (prefers-reduced-motion:reduce){.fw-trace-fr .draw{transition:none}}
.btn-row{display:flex;flex-wrap:wrap;gap:.7rem;align-items:center}

/* ══ 09 · FEATURE CARDS ═══════════════════════════════════ */
.fw-features{display:grid;gap:1rem}
.fw-features.up2{grid-template-columns:repeat(2,1fr)}
.fw-features.up3{grid-template-columns:repeat(3,1fr)}
.fw-features.up4{grid-template-columns:repeat(4,1fr)}
.fw-feature{background:var(--fw-card);border:1px solid var(--fw-rule);border-radius:var(--fw-r-lg);
  padding:1.15rem 1.25rem;display:flex;align-items:flex-start;gap:.9rem}
/* solid, un-faded accent — the wash version read too timid */
.fw-feature .ic{width:2.4rem;height:2.4rem;border-radius:var(--fw-r);display:grid;place-items:center;
  flex:none;background:var(--fw-accent,var(--fw-ocean));color:#fff}
.fw-feature .ic svg{width:1.3rem;height:1.3rem}
.fw-feature h4{font-size:.98rem;font-weight:700;letter-spacing:-.01em;margin-bottom:.2rem}
.fw-feature p{font-size:.89rem;color:var(--fw-ink-2);line-height:1.5}
@media (max-width:999px){.fw-features.up4,.fw-features.up3{grid-template-columns:repeat(2,1fr)}}
@media (max-width:689px){.fw-features.up2,.fw-features.up3,.fw-features.up4{grid-template-columns:1fr}}

/* ══ 10 · CHARTS ══════════════════════════════════════════ */
.fw-charts{display:grid;grid-template-columns:1.35fr 1fr 1fr;gap:1rem;align-items:start}
.fw-charts.two{grid-template-columns:1fr 1fr}
.fw-chart{background:var(--fw-card);border:1px solid var(--fw-rule);border-radius:var(--fw-r-lg);padding:1.25rem}
.fw-chart h4{font-size:.92rem;font-weight:700;margin-bottom:.15rem}
.fw-chart .cap{font-family:var(--fw-f-ui);font-size:.63rem;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--fw-ink-3);margin-bottom:1rem;display:block}
.fw-bars{display:flex;flex-direction:column;gap:.65rem}
.fw-bar{display:grid;grid-template-columns:5.5rem 1fr auto;align-items:center;gap:.7rem}
.fw-bar .lb{font-family:var(--fw-f-ui);font-size:.66rem;font-weight:700;letter-spacing:.07em;
  text-transform:uppercase;color:var(--fw-ink-2)}
.fw-bar .tr{height:.55rem;border-radius:999px;background:var(--fw-rule-2);overflow:hidden}
.fw-bar .fl{height:100%;border-radius:999px;background:var(--fw-accent,var(--fw-ocean));width:var(--fw-v)}
.fw-bar .vl{font-family:var(--fw-f-ui);font-size:.78rem;font-weight:700;
  font-variant-numeric:tabular-nums;color:var(--fw-ink)}
.fw-donut{display:flex;align-items:center;gap:1rem}
.fw-donut svg{width:6.5rem;height:6.5rem;flex:none;transform:rotate(-90deg)}
.fw-donut circle{fill:none;stroke-width:6.5}
.fw-donut .tr{stroke:var(--fw-rule-2)} .fw-donut .sg{stroke-linecap:butt}
.fw-legend{display:flex;flex-direction:column;gap:.45rem;font-family:var(--fw-f-ui);font-size:.66rem;
  font-weight:700;letter-spacing:.07em;text-transform:uppercase}
.fw-legend span{display:flex;align-items:center;gap:.45rem;color:var(--fw-ink-2)}
.fw-legend i{width:.7rem;height:.7rem;border-radius:3px;flex:none}
.fw-legend b{margin-left:auto;color:var(--fw-ink);font-variant-numeric:tabular-nums}
.fw-gauge{text-align:center}
.fw-gauge svg{width:100%;max-width:10rem;display:block;margin:0 auto}
.fw-gauge path{fill:none;stroke-width:7.5;stroke-linecap:round}
.fw-gauge .tr{stroke:var(--fw-rule-2)}
.fw-gauge .vl{stroke:var(--fw-accent,var(--fw-papaya));stroke-dasharray:100;stroke-dashoffset:calc(100 - var(--fw-v))}
.fw-gauge .num{font-family:var(--fw-f-display);font-size:1.7rem;font-weight:700;letter-spacing:-.03em;
  color:var(--fw-ink);display:block;margin-top:-1.5rem}
.fw-gauge .sub2{font-family:var(--fw-f-ui);font-size:.63rem;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--fw-ink-3);display:block;margin-top:.15rem}
/* seasonality strip — four RANKED tiers drawn from the palette (no red, no ink) */
.fw-season{display:grid;grid-template-columns:repeat(12,1fr);gap:3px}
.fw-season div{text-align:center}
.fw-season .cell{height:2.6rem;border-radius:4px;margin-bottom:.3rem}
.fw-season .t4 .cell{background:var(--fw-ocean)}   /* peak      */
.fw-season .t3 .cell{background:var(--fw-palm)}    /* good      */
.fw-season .t2 .cell{background:var(--fw-gold)}    /* shoulder  */
.fw-season .t1 .cell{background:var(--fw-papaya)}  /* avoid     */
.fw-season .m{font-family:var(--fw-f-ui);font-size:.6rem;font-weight:700;letter-spacing:.04em;color:var(--fw-ink-3)}
.fw-season-key{display:flex;flex-wrap:wrap;gap:.4rem .9rem;margin-top:.85rem;
  font-family:var(--fw-f-ui);font-size:.6rem;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--fw-ink-3)}
.fw-season-key span{display:flex;align-items:center;gap:.35rem}
.fw-season-key i{width:.65rem;height:.65rem;border-radius:3px;flex:none}
/* price range bar with a marker */
.fw-range{display:flex;flex-direction:column;gap:1.1rem}
.fw-rangerow .rl{font-family:var(--fw-f-ui);font-size:.66rem;font-weight:700;letter-spacing:.07em;
  text-transform:uppercase;color:var(--fw-ink-2);margin-bottom:1.55rem}
/* the typical-price label sits directly ABOVE its marker, not in the header row */
.fw-rangerow .tr{position:relative;height:.5rem;border-radius:999px;background:var(--fw-rule-2)}
.fw-rangerow .tip{position:absolute;left:var(--fw-avg);bottom:1.1rem;transform:translateX(-50%);
  white-space:nowrap;font-family:var(--fw-f-ui);font-size:.74rem;font-weight:700;color:var(--fw-ink)}
.fw-rangerow .tip::after{content:"";position:absolute;left:50%;bottom:-.42rem;width:1px;height:.35rem;
  background:var(--fw-accent,var(--fw-ocean));transform:translateX(-50%)}
.fw-rangerow .sp{position:absolute;top:0;bottom:0;border-radius:999px;
  background:var(--fw-accent,var(--fw-ocean));opacity:.28;left:var(--fw-lo);right:var(--fw-hi)}
.fw-rangerow .mk{position:absolute;top:50%;left:var(--fw-avg);width:.85rem;height:.85rem;
  border-radius:50%;background:var(--fw-accent,var(--fw-ocean));border:2px solid var(--fw-card);
  transform:translate(-50%,-50%)}
.fw-rangerow .sc{display:flex;justify-content:space-between;font-family:var(--fw-f-ui);
  font-size:.66rem;color:var(--fw-ink-3);margin-top:.35rem}
@media (max-width:999px){.fw-charts{grid-template-columns:1fr 1fr}.fw-charts.two{grid-template-columns:1fr}}
@media (max-width:689px){
  .fw-charts,.fw-charts.two{grid-template-columns:1fr}
  .fw-season{grid-template-columns:repeat(6,1fr)}
}

/* ══ 11 · ARTICLE HERO + GALLERY ══════════════════════════ */
.fw-hero{position:relative;border-radius:var(--fw-r-lg);overflow:hidden;background:var(--fw-ink);
  min-height:22rem;display:flex;align-items:flex-end;isolation:isolate}
.fw-hero .bg{position:absolute;inset:0;z-index:-2;
  background:linear-gradient(155deg,#12303A 0%,#1D4E5C 42%,#3A6E70 70%,#7E8A66 100%)}
.fw-hero .scrim{position:absolute;inset:0;z-index:-1;
  background:linear-gradient(180deg,rgba(12,20,24,.15) 30%,rgba(12,20,24,.82) 100%)}
.fw-hero .body{padding:1.9rem;color:#fff;max-width:46rem}
.fw-hero .kicker{display:inline-flex;align-items:center;gap:.45rem;font-family:var(--fw-f-ui);
  font-size:.64rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  background:var(--fw-red);color:#fff;padding:.3rem .7rem;border-radius:999px;margin-bottom:.9rem}
.fw-hero h3{font-size:clamp(1.7rem,4.2vw,2.7rem);font-weight:700;letter-spacing:-.03em;
  line-height:1.06;margin-bottom:.6rem}
.fw-hero .dek{font-size:1rem;color:rgba(255,255,255,.86);max-width:38rem}
.fw-hero .meta{display:flex;flex-wrap:wrap;gap:.5rem 1.2rem;margin-top:1.1rem;
  font-family:var(--fw-f-ui);font-size:.66rem;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:rgba(255,255,255,.68)}
.fw-hero .meta b{color:#fff;font-weight:700}
@media (max-width:689px){.fw-hero{min-height:17rem}.fw-hero .body{padding:1.25rem}}
/* gallery — same snap mechanic as the comparison deck */
.fw-gal{margin-top:1rem}
.fw-gal-track{display:flex;gap:.7rem;overflow-x:auto;scroll-snap-type:x mandatory;
  scrollbar-width:none;padding-bottom:.5rem;scroll-timeline-name:--gal;scroll-timeline-axis:inline}
.fw-gal-track::-webkit-scrollbar{display:none}
.fw-gal-track figure{flex:0 0 42%;scroll-snap-align:start;margin:0}
.fw-gal-track .ph{aspect-ratio:4/3;border-radius:var(--fw-r);background:var(--fw-sand);
  border:1px solid var(--fw-rule);display:grid;place-items:center;
  font-family:var(--fw-f-data);font-size:.58rem;letter-spacing:.1em;color:var(--fw-ink-3)}
.fw-gal-track figcaption{font-family:var(--fw-f-ui);font-size:.7rem;color:var(--fw-ink-3);margin-top:.4rem}
@media (max-width:689px){.fw-gal-track figure{flex:0 0 76%}}

.footnote{border-top:1px solid var(--fw-ink);padding:1.25rem 0 3rem;font-family:var(--fw-f-ui);
  font-size:.78rem;color:var(--fw-ink-3);line-height:1.7}
