/* ══════════════════════════════════════════════════════════════════
   fenmore — components

   Hand-written. References ONLY the tokens in fenmore.css, never a raw
   value. That separation means regenerating tokens never clobbers
   components, and a reskin needs no changes here at all.

   Everything is scoped under .fenmore. Compose mock screens from these
   and screenshot at 2x — faster than redrawing in Figma, consistent by
   construction, and reskinnable in one edit.
   ══════════════════════════════════════════════════════════════════ */

.fenmore{
  font: var(--fen-text-body);
  letter-spacing: var(--fen-track-body);
  color: var(--fen-color-text-primary);
  background: var(--fen-color-surface-page);
  -webkit-font-smoothing: antialiased;
}
.fenmore *{ box-sizing: border-box }
.fenmore img{ max-width:100%; display:block }

/* ── layout ─────────────────────────────────────────────────────── */
.fen-container{ max-width:var(--fen-size-container-max); margin:0 auto;
  padding:0 var(--fen-space-5) }
.fen-stack > * + *{ margin-top:var(--fen-space-4) }
.fen-screen{ background:var(--fen-color-surface-page);
  border:var(--fen-border-default);
  border-radius:var(--fen-radius-md); overflow:hidden }

/* ── nav ────────────────────────────────────────────────────────── */
.fen-nav{
  background:var(--fen-color-surface-chrome);
  min-height:var(--fen-size-nav-height);
  display:flex; align-items:center; gap:var(--fen-space-5);
  padding:0 var(--fen-space-5);
}
.fen-monogram{
  width:22px; height:22px; border-radius:var(--fen-radius-sm);
  background:var(--fen-color-text-brand);
  flex:0 0 auto;
  /* the monogram is the ONLY place the brand colour appears as a
     figure — 5.7:1 on chrome. It is fill-only on light surfaces. */
}
.fen-wordmark{
  font: var(--fen-text-subheading);
  letter-spacing: var(--fen-track-subheading);
  color:var(--fen-color-text-on-chrome);
}
.fen-nav-links{ display:flex; gap:var(--fen-space-4); margin-left:auto }
.fen-nav-links a{
  font: var(--fen-text-body-sm);
  letter-spacing: var(--fen-track-body-sm);
  color:var(--fen-color-text-on-chrome);
  text-decoration:none; opacity:.85;
}
.fen-nav-links a:hover{ opacity:1 }
.fen-nav-links a[aria-current]{ opacity:1; font-weight:var(--fen-font-weight-medium) }

/* second-level bar — category / audience switch */
.fen-subnav{
  background:var(--fen-color-surface-chrome-deep);
  display:flex; gap:var(--fen-space-4);
  padding:var(--fen-space-3) var(--fen-space-5);
}
.fen-subnav a{
  font: var(--fen-text-label);
  color:var(--fen-color-text-on-chrome);
  text-decoration:none; opacity:.8;
}

/* ── dropdown panel ─────────────────────────────────────────────── */
.fen-panel{
  background:var(--fen-color-surface-raised);
  box-shadow:var(--fen-shadow-dropdown);
  border-radius:0 0 var(--fen-radius-md) var(--fen-radius-md);
  padding:var(--fen-space-5);
  display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:var(--fen-space-5);
}
.fen-panel h4{
  font: var(--fen-text-label);
  color:var(--fen-color-text-secondary);
  text-transform:var(--fen-case-label); letter-spacing:var(--fen-track-label);
  margin:0 0 var(--fen-space-2);
}
.fen-panel ul{ list-style:none; margin:0; padding:0 }
.fen-panel li + li{ margin-top:var(--fen-space-2) }
.fen-panel a{
  font: var(--fen-text-body-sm);
  letter-spacing: var(--fen-track-body-sm);
  color:var(--fen-color-interactive-default);
  text-decoration:none;
}
.fen-panel a:hover{ color:var(--fen-color-interactive-hover); text-decoration:underline }
/* the count treatment — the single most transferable decision in the
   navigation case study. Tells you the size of what's behind a link
   before you spend a click on it. */
.fen-count{ color:var(--fen-color-text-muted); font-variant-numeric:tabular-nums }

/* ── chips ──────────────────────────────────────────────────────── */
/* ── chips ───────────────────────────────────────────────────────────
   HAIRLINE AT REST, FILLED WHEN SELECTED.

   The old chip was filled at rest, which left selection nowhere to go —
   every chip already looked switched on, so the row read as a stack of
   buttons rather than a set of filters. A fill reads as state; a rule
   reads as an affordance. Same principle as the portfolio's annotations.

   Selection is the one job chartreuse has. It is the loudest value in
   the palette, and it is scarce because only some chips are selected —
   which is exactly the opposite of using it on five column headers at
   once, where loud plus everywhere equals meaningless. */
.fen-chips{ display:flex; flex-wrap:wrap; gap:var(--fen-space-2) }
.fen-chip{
  /* action, not label — a chip holds content ("Business"), and label
     bakes in uppercase, which is for column heads. */
  font: var(--fen-text-action);
  letter-spacing: var(--fen-track-action);
  display:inline-flex; align-items:center; gap:var(--fen-space-2);
  background:transparent;
  color:var(--fen-color-text-primary);
  border:var(--fen-border-strong);
  border-radius:var(--fen-radius-pill);
  padding:var(--fen-space-2) var(--fen-space-3);
  cursor:pointer; white-space:nowrap;
}
/* The count is secondary information and is coloured that way, not
   shrunk — two sizes inside one pill is one size too many. */
.fen-chip b, .fen-chip .fen-count{ font-weight:var(--fen-font-weight-regular);
  color:var(--fen-color-text-secondary) }

/* Hover lifts the surface. Works on both surfaces unchanged: raised is
   white on light and chrome-700 on inverse, because raised means
   "nearer the viewer", not "lighter". */
.fen-chip:hover{
  background:var(--fen-color-surface-raised);
  border-color:var(--fen-color-interactive-default);
}
.fen-chip[aria-pressed="true"]{
  background:var(--fen-color-selected-fill);
  color:var(--fen-color-selected-text);
  /* brand/700 is the ramp's dead zone — fails as text on every surface in
     the system. Which makes it exactly right here: a chartreuse pill on
     white is 1.8:1 and has no visible edge without it. 3.6:1 as a
     non-text border clears the UI-component threshold. */
  border-color:var(--fen-color-selected-edge);
}
/* Inside a selected chip the count steps down by WEIGHT, not opacity —
   opacity on text is how you get a 3:1 label you didn't measure. */
.fen-chip[aria-pressed="true"] b,
.fen-chip[aria-pressed="true"] .fen-count{
  color:inherit; font-weight:var(--fen-font-weight-regular)
}
.fen-chip:focus-visible{
  outline:var(--fen-border-focus); outline-offset:2px; border-color:transparent;
}
/* Icons ride at text size in the current colour. The bright circular
   glyphs in the first pass were the highest-contrast element on the
   screen and carried the least information in it. */
.fen-chip svg, .fen-chip img{
  width:16px; height:16px; flex:0 0 auto; color:currentColor;
}

/* ── buttons ─────────────────────────────────────────────────────────
   THREE TIERS, SEPARATED ON TWO AXES EACH.

   primary   = fill, no border
   secondary = border, no fill
   ghost     = neither

   Never fill-strength alone: a trio told apart only by how saturated
   its fill is collapses in greyscale, at a glance, and for anyone with
   low colour vision. The original pair failed this — two teal fills of
   similar value reading as two equal primaries.

   All three work on both surfaces from one class, because they
   reference semantic names that .fen-inverse remaps. */
.fen-btn{
  font: var(--fen-text-action);
  letter-spacing: var(--fen-track-action);
  min-height:var(--fen-size-control);
  padding:0 var(--fen-space-4);
  border-radius:var(--fen-radius-sm);
  /* transparent hairline on every tier so swapping tiers never shifts
     layout by a pixel */
  border:var(--fen-borderWidth-hairline) solid transparent;
  cursor:pointer; display:inline-flex; align-items:center;
  justify-content:center; gap:var(--fen-space-2);
  text-decoration:none;
}
.fen-btn svg{ width:16px; height:16px; flex:0 0 auto }

/* PRIMARY — one per view. The filled thing is the thing you meant. */
.fen-btn--primary{
  background:var(--fen-color-interactive-default);
  color:var(--fen-color-text-on-accent);
}
.fen-btn--primary:hover{ background:var(--fen-color-interactive-hover) }
/* On the inverse the fill is the light accent, so the label has to flip
   dark — a filled button is its own surface and gets its own text role. */
.fen-inverse .fen-btn--primary{
  background:var(--fen-inverse-interactive);
  color:var(--fen-inverse-text-on-selected);
}
.fen-inverse .fen-btn--primary:hover{ background:var(--fen-inverse-interactive-hover) }

/* SECONDARY — the edge does the work. */
.fen-btn--secondary{
  background:transparent;
  color:var(--fen-color-interactive-default);
  border-color:var(--fen-color-border-strong);
}
.fen-btn--secondary:hover{
  border-color:var(--fen-color-interactive-default);
  background:var(--fen-color-interactive-subtle);
}
.fen-inverse .fen-btn--secondary:hover{
  background:var(--fen-inverse-surface-raised);
}

/* GHOST — no fill, no border, but the SAME box. Keeping the padding and
   min-height is the whole point: a ghost that collapses to bare text
   can't sit in a row with the other two. */
.fen-btn--ghost{
  background:transparent;
  color:var(--fen-color-interactive-default);
}
.fen-btn--ghost:hover{ background:var(--fen-color-interactive-subtle) }
.fen-inverse .fen-btn--ghost{ color:var(--fen-color-text-primary) }
.fen-inverse .fen-btn--ghost:hover{ background:var(--fen-inverse-surface-raised) }

/* DEPRECATED — an underlined link masquerading as a button. Aliased to
   ghost so existing markup keeps working. */
.fen-btn--tertiary{
  background:transparent; color:var(--fen-color-interactive-default);
}
.fen-btn--tertiary:hover{ background:var(--fen-color-interactive-subtle) }

.fen-btn:focus-visible{
  outline:var(--fen-border-focus);
  outline-offset:2px;
}
.fen-btn[disabled]{
  opacity:var(--fen-opacity-disabled); cursor:not-allowed;
}

.fen-sticky .fen-btn{ margin-left:auto }

/* ── section header inside a screen ─────────────────────────────── */
.fen-section-head{
  display:flex; align-items:baseline; gap:var(--fen-space-3);
  padding:var(--fen-space-5) 0 var(--fen-space-4);
}
.fen-section-head h2{ font: var(--fen-text-heading); margin:0 }
.fen-section-head .fen-count{ font: var(--fen-text-body-sm) }

/* ── card art ────────────────────────────────────────────────────────
   Real credit-card proportion, 1.586:1. A flat rectangle where a card
   should be is the most obvious placeholder in an abstracted screen, so
   these carry the tier gradients. The label colour is NOT chosen here —
   it comes from the gradient's own gate, which walked every stop. */
.fen-card-art{
  aspect-ratio:1.586 / 1;
  border-radius:var(--fen-radius-lg);
  padding:var(--fen-space-4);
  display:flex; flex-direction:column; justify-content:space-between;
  box-shadow:var(--fen-shadow-card);
  color:var(--fen-color-text-on-accent);      /* white — three of four tiers */
}
.fen-card-art--standard{ background:var(--fen-gradient-card-standard) }
.fen-card-art--premium { background:var(--fen-gradient-card-premium) }
.fen-card-art--business{ background:var(--fen-gradient-card-business) }
/* the only face with an ink label, per the gate */
.fen-card-art--starter {
  background:var(--fen-gradient-card-starter);
  color:var(--fen-color-text-primary);
}
.fen-card-art .fen-ca-brand{ font:var(--fen-text-subheading);
  letter-spacing:var(--fen-track-subheading) }
.fen-card-art .fen-ca-tier{ font:var(--fen-text-label);
  letter-spacing:var(--fen-track-label); text-transform:var(--fen-case-label);
  opacity:var(--fen-opacity-subtle) }
.fen-card-art .fen-ca-foot{ display:flex; justify-content:space-between;
  align-items:flex-end }
.fen-card-art .fen-ca-digits{ font:var(--fen-text-body-sm);
  letter-spacing:var(--fen-track-label) }

/* ── media with a scrim ──────────────────────────────────────────────
   The scrim's 30% crossing point sits at 52%, so the caption is pinned
   below that. Reproducing the stop position by eye is how a hero caption
   ends up at 3:1. */
.fen-media{ position:relative; overflow:hidden;
  border-radius:var(--fen-radius-md) }
.fen-media img{ display:block; width:100%; height:100%; object-fit:cover }
.fen-media::after{ content:""; position:absolute; inset:0;
  background:var(--fen-gradient-scrim-bottom); pointer-events:none }
.fen-media--topnav::after{ background:var(--fen-gradient-scrim-top) }
.fen-media .fen-media-cap{
  position:absolute; left:var(--fen-space-4); right:var(--fen-space-4);
  bottom:var(--fen-space-4); z-index:1;
  color:var(--fen-color-text-on-accent);
  max-height:44%;                     /* stays under the 52% stop */
}

/* ── scrolling rail with edge fades ──────────────────────────────────
   The affordance that says content continues past the edge. The fades
   are tokens with live var() references, so they follow .fen-inverse
   instead of fading to white over a dark bar. */
.fen-rail{ position:relative }
.fen-rail-track{ display:flex; gap:var(--fen-space-2);
  overflow-x:auto; scroll-behavior:smooth;
  scrollbar-width:thin; padding:2px }
.fen-rail::before, .fen-rail::after{
  content:""; position:absolute; top:0; bottom:0; width:56px;
  pointer-events:none; opacity:0; transition:opacity .15s ease;
}
.fen-rail::before{ left:0;  background:var(--fen-gradient-fade-left) }
.fen-rail::after { right:0; background:var(--fen-gradient-fade-right) }
/* toggled by script — a fade showing when there's nothing to scroll to
   is a lie about the content */
.fen-rail[data-overflow~="start"]::before{ opacity:1 }
.fen-rail[data-overflow~="end"]::after{ opacity:1 }

/* ── featured row ─────────────────────────────────────────────────── */
.fen-featured{ border:var(--fen-border-default);
  border-radius:var(--fen-radius-md); overflow:hidden;
  background:var(--fen-color-surface-raised) }
.fen-featured::before{ content:""; display:block; height:4px;
  background:var(--fen-gradient-tier) }
.fen-featured > *{ padding:var(--fen-space-4) }

/* ── new elevations ──────────────────────────────────────────────── */
.fen-card:hover, .fen-elev-hover{ box-shadow:var(--fen-shadow-card-hover) }
.fen-modal{ box-shadow:var(--fen-shadow-modal);
  border-radius:var(--fen-radius-md);
  background:var(--fen-color-surface-raised) }
/* a bottom-anchored bar throws its shadow UP */
.fen-sticky{ box-shadow:var(--fen-shadow-sticky) }
.fen-field--sunken, .fen-inset{ box-shadow:var(--fen-shadow-inset);
  background:var(--fen-color-surface-sunken) }

/* ── skeleton ────────────────────────────────────────────────────── */
.fen-skeleton{ background:var(--fen-gradient-skeleton);
  background-size:400% 100%; border-radius:var(--fen-radius-pill);
  height:.875em; animation:fen-shimmer 1.4s linear infinite }
@keyframes fen-shimmer{ from{background-position:100% 0}
                        to{background-position:0 0} }
@media (prefers-reduced-motion:reduce){
  .fen-skeleton{ animation:none }
}
