/* ═══════════════════════════════════════════════════════════════════════════
   fan.css — the PennaSystems feather fan, extracted so a page that is NOT on
   the cream pennasystems palette can render it.

   WHY THIS FILE EXISTS (root IA merge, 2026-08-31)
   ------------------------------------------------
   The fan's styles used to live only in `frontend/pennasystems-styles.css`,
   the cream marketing stylesheet. The merged root (`frontend/index.html`) is
   on the PennaPay white/slate/gold palette (`css/pennapay-theme.css`, see
   `project_marketing_dark_mode`) and must NEVER load the cream sheet — that is
   the documented theming trap. So the fan rules are lifted here, verbatim in
   behaviour, and made palette-agnostic: every colour and font goes through a
   token with a fallback, so the host page decides what the fan looks like by
   defining --ink / --ink-2 / --muted / --rule / --paper-hi / --serif / --mono.

   `pennasystems-index.html` (the /suite hub) is deliberately UNTOUCHED and
   still gets these rules from pennasystems-styles.css. That is duplication on
   purpose: the alternative is the root pulling in the whole cream stylesheet.

   Markup is generated by `frontend/pennasystems-fan.js` — do not hand-author
   .fan-* elements. The geometry comments live in that file.
   ═══════════════════════════════════════════════════════════════════════════ */

/* The fan's buttons are generated, so they never pick up a page's own button
   styling. Reset them here rather than relying on the host page. */
.fan button,
.mobile-fan button {
  font: inherit; color: inherit; background: none;
  border: 0; padding: 0; margin: 0; cursor: pointer; text-align: left;
}

/* ── The fan itself. Pivot at bottom-centre. ─────────────────────────────── */
/* Column layout: the stage on top, the legend strip (rendered by fan.js)
   below it. align-items keeps both centred. */
.fan { width: 100%; display: flex; flex-direction: column; align-items: center; }
.fan-stage {
  position: relative;
  width: var(--fan-size); height: calc(var(--fan-size) * 1.05);
  /* Press-and-drag scrubbing: claim touch gestures on the fan itself so a
     finger dragging across the feathers selects them instead of scrolling
     the page. Scoped to the stage only — the rest of the page scrolls. */
  touch-action: none;
}
.fan-feather {
  position: absolute; left: 50%; bottom: 0;
  width: var(--fan-size); height: var(--fan-size);
  /* nib of the feather glyph sits at (64,174) inside the 200x200 viewBox,
     i.e. 32% from the left and 87% from the top — rotation pivots there.
     --tx/--ty/--rot are set per-feather by renderDesktopFan. */
  transform-origin: 32% 87%;
  transform: translate(var(--tx, -32%), var(--ty, 0)) rotate(var(--rot, 0deg));
  transition: transform .35s cubic-bezier(.2,.7,.2,1), opacity .25s, filter .25s;
  cursor: pointer;
}
.fan-feather:focus-visible { outline: none; }
.fan-feather:focus-visible svg { filter: drop-shadow(0 0 0 2px var(--ink, #0f172a)); }
.fan-feather svg { position: absolute; inset: 0; }
/* Hover/active lift travels along the feather's own spine so a feather pushes
   outward toward its tip instead of jumping straight up in screen space.
   Deliberately NOT driven by native :hover — the feather buttons are large
   overlapping rotated squares, so native hit-testing picks whichever button is
   on top at that pixel. renderDesktopFan() does its own angle-based hit test
   and toggles .is-active on the correct feather instead. */
.fan-feather.is-active {
  transform: translate(var(--tx, -32%), var(--ty, 0)) rotate(var(--rot, 0deg)) translateY(-8%);
  transition: transform 200ms ease;
}
/* One-time roll-call lift (fan.js adds/removes .is-lifted per feather in
   sequence on first viewport entry). */
.fan-feather.is-lifted {
  transform: translate(var(--tx, -32%), var(--ty, 0)) rotate(var(--rot, 0deg)) translateY(-8%);
  transition: transform 300ms cubic-bezier(.2,.7,.2,1);
}
/* Resting default-active feather: gently raised (about half the hover lift). */
.fan-feather.is-resting {
  transform: translate(var(--tx, -32%), var(--ty, 0)) rotate(var(--rot, 0deg)) translateY(-4.5%);
}
.fan-feather.is-dim { opacity: 0.32; }
.fan-feather.is-front svg { filter: drop-shadow(0 4px 0 rgba(0,0,0,.04)); }

.fan-flag {
  /* left/top are set per-feather to the tip coordinate (stage space); the
     translate lifts the label clear of the tip and centres it on it. Hidden
     until its feather is highlighted (JS toggles .is-visible). */
  position: absolute; z-index: 200;
  transform: translate(-50%, -150%);
  font-family: var(--mono, ui-monospace, Menlo, monospace);
  font-size: 11px; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity 160ms ease;
}
.fan-flag.is-visible { opacity: 1; }

/* Floating tool name that tracks the fingertip during a touch scrub. */
.fan-touch-label {
  position: absolute; z-index: 210; left: 0; top: 0;
  transform: translate(-50%, -220%);
  font-family: var(--serif, Georgia, serif); font-size: 17px; font-weight: 500;
  letter-spacing: -0.01em; white-space: nowrap;
  padding: 4px 12px; border-radius: 999px;
  background: var(--paper-hi, #fff); border: 1px solid var(--rule, #e2e8f0);
  box-shadow: 0 6px 18px rgba(0,0,0,.12);
  pointer-events: none; opacity: 0; transition: opacity 120ms ease;
}
.fan-touch-label.is-visible { opacity: 1; }

/* Name pill anchored to a feather's tip (stage space, like .fan-flag). Shown
   per-feather during the one-time roll-call sweep and on the resting
   default-active feather — never on ordinary hover, which keeps the tooltip
   below the fan as its label surface. */
.fan-name-pill {
  position: absolute; z-index: 205;
  color: var(--pill-color, var(--ink, #0f172a));
  transform: translate(-50%, -160%);
  font-family: var(--serif, Georgia, serif); font-size: 15px; font-weight: 500;
  letter-spacing: -0.01em; white-space: nowrap;
  padding: 3px 11px; border-radius: 999px;
  background: var(--paper-hi, #fff); border: 1px solid var(--rule, #e2e8f0);
  box-shadow: 0 4px 14px rgba(0,0,0,.10);
  pointer-events: none; opacity: 0; transition: opacity 180ms ease;
}
.fan-name-pill.is-visible { opacity: 1; }
/* Feathers that also carry a "soon" flag: lift the pill clear so the two stack
   (name above, SOON below) instead of overlapping at the tip. */
.fan-name-pill.has-flag { transform: translate(-50%, -215%); }
/* Inboard placement (near-vertical feathers): fan.js anchors these on the
   upper feather body rather than the tip, so centre on the anchor. */
.fan-name-pill.is-inboard { transform: translate(-50%, -50%); }

/* Legend strip — persistent glyph + name chips under the fan, rendered by
   fan.js on the desktop layout only (the mobile list already shows names).
   margin-top clears the fan's below-stage feather overhang; tuned for
   size:220. */
.fan-legend {
  margin-top: 152px;
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 8px 10px; padding: 0 24px;
}
.fan-legend-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 13px; border: 1px solid var(--rule, #e2e8f0); border-radius: 999px;
  background: var(--paper-hi, #fff);
  font-family: var(--mono, ui-monospace, Menlo, monospace);
  font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-2, #475569); text-decoration: none;
  transition: border-color 120ms ease, color 120ms ease, transform 120ms ease;
}
.fan-legend-chip:hover { border-color: var(--ink, #0f172a); color: var(--ink, #0f172a); transform: translateY(-1px); }
.fan-legend-chip:focus-visible {
  border-color: var(--ink, #0f172a); color: var(--ink, #0f172a);
  outline: 2px solid var(--ink, #0f172a); outline-offset: 2px;
}
.fan-legend-glyph { height: 15px; width: auto; display: block; transform: rotate(-12deg); flex-shrink: 0; }
.fan-legend-soon {
  font-family: var(--mono, ui-monospace, Menlo, monospace);
  font-size: 8.5px; letter-spacing: 0.1em;
  color: var(--muted, #64748b); border: 1px solid var(--rule, #e2e8f0); border-radius: 999px;
  padding: 1px 6px; line-height: 1.4;
}

@media (prefers-reduced-motion: reduce) {
  .fan-feather, .fan-name-pill, .fan-legend-chip { transition: none; }
}

/* ── Centred fan block (the layout the merged root and the /suite hub use) ── */
.fan-centered {
  position: relative; width: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  /* The fan paints well outside its fan-stage box: near-vertical feathers
     extend above the stage top, horizontal feathers swing below the nib.
     padding-top reserves room for the top overhang AND visual breathing room
     to the suite-head text above. Tuned for renderFan size:220 — re-tune if
     that changes. */
  padding-top: 104px;
  min-height: 568px;
  overflow: visible;
}
.fan-centered #fan-container { position: relative; }
.fan-centered .fan-stage { overflow: visible; }

.fan-below {
  /* The feather-overhang clearance (152px) lives on .fan-legend, which sits
     between the stage and this block — so this only needs a small gap. */
  margin-top: 28px;
  position: relative;
  width: min(420px, 90vw);
}

.fan-tooltip {
  position: relative;
  width: 100%;
  background: var(--paper-hi, #fff); border: 1px solid var(--rule, #e2e8f0);
  padding: 22px 24px; border-radius: 4px;
  display: flex; flex-direction: column; gap: 8px;
  opacity: 0; pointer-events: none;
  transition: opacity 160ms ease;
  text-align: center;
  box-shadow: 0 12px 32px rgba(0,0,0,.08);
}
.fan-tooltip.is-visible { opacity: 1; pointer-events: auto; }
.fan-tooltip .tip-name { font-family: var(--serif, Georgia, serif); font-size: 26px; font-weight: 500; letter-spacing: -0.01em; }
.fan-tooltip .tip-tag { font-size: 15px; color: var(--ink, #0f172a); font-weight: 500; }
.fan-tooltip .tip-blurb { font-size: 14px; color: var(--ink-2, #475569); line-height: 1.55; }
.fan-tooltip .tip-cta { font-size: 13px; font-weight: 500; color: var(--ink, #0f172a); border-top: 1px solid var(--rule, #e2e8f0); padding-top: 12px; margin-top: 4px; }

/* Plain sentence, not an uppercase letter-spaced label (de-AI pass). It is an
   instruction to the reader, so it should read like one. */
.fan-hint { font-size: 13px; color: var(--muted, #64748b); }
.fan-centered .fan-hint {
  /* Overlaid on the .fan-below area; fades out when the tooltip appears. */
  position: absolute; top: 18px; left: 50%; transform: translateX(-50%);
  white-space: nowrap; margin: 0; transition: opacity 160ms ease;
}

@media (max-width: 720px) {
  .fan-centered { min-height: auto; padding-top: 0; }
  .fan-below { margin-top: 24px; }
  .fan-tooltip { opacity: 1; pointer-events: auto; }
  .fan-tooltip:not(.is-visible) { display: none; }
}

/* ── Mobile fan — .m-* classes emitted by renderMobileFan() below 700px. ─── */
.mobile-fan { width: 100%; }
.m-list { display: flex; flex-direction: column; }
.m-item { border-bottom: 1px solid var(--rule, #e2e8f0); }
.m-item:first-child { border-top: 1px solid var(--rule, #e2e8f0); }
.m-row {
  display: flex; align-items: center; gap: 16px;
  padding: 14px 0; cursor: pointer;
}
.m-feather { flex-shrink: 0; width: 56px; height: 56px; }
.m-feather svg { width: 56px; height: 56px; }
.m-row-text { flex: 1; min-width: 0; }
.m-row-name {
  font-family: var(--serif, Georgia, serif); font-size: 16px; font-weight: 500;
  color: var(--ink, #0f172a); display: flex; align-items: center; gap: 8px; line-height: 1.2;
}
.m-soon {
  font-family: var(--mono, ui-monospace, Menlo, monospace);
  font-size: 9px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted, #64748b);
  border: 1px solid var(--rule, #e2e8f0); border-radius: 999px;
  padding: 2px 7px; line-height: 1.4; flex-shrink: 0;
}
.m-row-tag { font-size: 13px; color: var(--ink-2, #475569); margin-top: 3px; line-height: 1.4; }
.m-row-chev { color: var(--muted, #64748b); font-size: 14px; flex-shrink: 0; transition: transform 160ms ease; }
.m-row:hover .m-row-chev, .m-row:active .m-row-chev { transform: translateX(3px); }
.m-row:active { opacity: 0.75; }

/* Fan caption per input type. Hover devices read the mouse hint; touch devices
   that get the interactive fan (>=700px, where renderFan draws the radial fan
   rather than the tappable list) read the press-and-drag hint. Touch + narrow
   viewport shows the mobile list, which is self-explanatory. */
.fan-hint-touch { display: none; }
@media (hover: none) {
  .fan-hint-hover { display: none; }
}
@media (hover: none) and (min-width: 700px) {
  .fan-hint-touch { display: inline; }
}
