/* ============================================================================
   fat_protein_sizes.css — the size-ladder widget.

   Self-contained: every site token has a literal fallback, so the widget looks
   right on a topic page, an admin page, or the standalone demo file.
   The full-page surface uses the shared --fadb-fp-z token (components/ui/fullpage).
   ========================================================================= */

.fps-widget {
    --fps-h: 470px;                       /* canvas height, inline */
    --fps-list-w: 232px;
    --fps-field: #eef2f7;                 /* the "field of view" behind the strip */
    --fps-field-2: #e2e8f0;
    --fps-ink: var(--text-main, #2c3e50);
    --fps-muted: var(--text-muted, #64748b);
    --fps-line: var(--border-color, #e2e8f0);
    --fps-accent: var(--primary-color, #3b82f6);
    --fps-chip: rgba(255, 255, 255, 0.8);   /* readable over any artwork */

    margin: 1.75rem 0;
    border: 1px solid var(--fps-line);
    border-radius: var(--radius-md, 0.5rem);
    background: var(--bg-card, #fff);
    overflow: hidden;
    font-family: var(--font-family, system-ui, sans-serif);
    color: var(--fps-ink);
}

body.dark-mode .fps-widget {
    --fps-field: #131a24;
    --fps-field-2: #0c1119;
    --fps-chip: rgba(13, 17, 23, 0.78);
}

/* ── layout ──────────────────────────────────────────────────────────────── */
.fps-shell {
    display: grid;
    grid-template-columns: var(--fps-list-w) minmax(0, 1fr);
    align-items: stretch;
}

.fps-list {
    border-right: 1px solid var(--fps-line);
    background: var(--bg-body, #f4f6f8);
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.fps-list-head {
    padding: 0.6rem 0.75rem 0.45rem;
    font-size: var(--fs-3xs, 0.65rem);
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--fps-muted);
    border-bottom: 1px solid var(--fps-line);
}

/* No scrollbar, on purpose. The list is the widget's table of contents — a
   reader should see every item without discovering there are more below the
   fold. It grows to its natural height and the canvas grows with it (see
   .fps-stage), so adding an item makes the widget taller, never scrollable.
   flex:1 is what carries the panel's background all the way to the bottom
   when the canvas is the taller of the two. */
.fps-list-items {
    flex: 1;
    padding: 0.3rem;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

/* ── a list row ──────────────────────────────────────────────────────────── */
.fps-row {
    display: grid;
    grid-template-columns: 1.35rem minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.45rem;
    width: 100%;
    padding: 0.34rem 0.45rem;
    border: 0;
    border-radius: var(--radius-sm, 0.25rem);
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
    line-height: 1.2;
}
.fps-row:hover { background: var(--hover-bg, rgba(0, 0, 0, 0.05)); }
.fps-row:focus-visible { outline: 2px solid var(--fps-accent); outline-offset: -2px; }
.fps-row.is-active {
    background: var(--fps-accent);
    color: var(--on-accent, #fff);
}
.fps-row.is-active .fps-row-type,
.fps-row.is-active .fps-row-size,
.fps-row.is-active .fps-row-i { color: inherit; opacity: 0.85; }

.fps-row-i {
    font-size: var(--fs-4xs, 0.6rem);
    font-variant-numeric: tabular-nums;
    color: var(--fps-muted);
    text-align: right;
}
.fps-row-mid { min-width: 0; }

/* Category over specimen: "FATTY ACID" above "DHA". An item with no category
   (the hair) centres its name instead, so rows keep one rhythm. */
.fps-row-type {
    display: block;
    font-size: var(--fs-4xs, 0.6rem);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--fps-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.fps-row-name {
    display: block;
    font-size: var(--fs-sm, 0.85rem);
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.fps-row-mid--notype { padding: 0.28rem 0; }
.fps-row-size {
    font-size: var(--fs-2xs, 0.72rem);
    font-variant-numeric: tabular-nums;
    color: var(--fps-muted);
    white-space: nowrap;
}

/* ── canvas ──────────────────────────────────────────────────────────────── */
.fps-canvas-wrap {
    min-width: 0;
    display: flex;
    flex-direction: column;
}

/* The stage is the positioning context for the tools and the scale bar. The
   caption sits outside it, so a caption of any length can never end up under
   the scale bar. */
.fps-stage {
    position: relative;
    min-width: 0;
    display: flex;
    /* Absorbs any height the item list adds beyond --fps-h, so a longer list
       makes the picture taller rather than making the list scroll. */
    flex: 1 1 auto;
    min-height: var(--fps-h);
}

.fps-canvas {
    display: block;
    width: 100%;
    height: 100%;
    min-height: var(--fps-h);
    background:
        radial-gradient(120% 90% at 50% 100%, var(--fps-field) 0%, var(--fps-field-2) 100%);
    touch-action: none;
    cursor: grab;
    -webkit-user-select: none;
    user-select: none;
}
.fps-canvas:focus-visible { outline: 2px solid var(--fps-accent); outline-offset: -2px; }
.fps-canvas.is-panning { cursor: grabbing; }

.fps-widget:not(.is-ready) .fps-canvas { opacity: 0; }
.fps-widget:not(.is-ready) .fps-stage::after {
    content: 'Loading…';
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-size: var(--fs-sm, 0.85rem);
    color: var(--fps-muted);
}

/* items and their marks */
.fps-item { cursor: pointer; }
.fps-item.is-active { filter: drop-shadow(0 0 6px rgba(59, 130, 246, 0.75)); }

.fps-baseline {
    stroke: var(--fps-muted);
    stroke-width: 1;
    opacity: 0.35;
}
.fps-speck { fill: var(--fps-muted); opacity: 0.7; }

.fps-bar {
    fill: none;
    stroke: var(--fps-muted);
    stroke-width: 1.25;
    opacity: 0.9;
}
.fps-lbl-name, .fps-lbl-size {
    text-anchor: middle;
    fill: var(--fps-ink);
    paint-order: stroke;
    stroke: var(--fps-field);
    stroke-width: 3px;
    stroke-linejoin: round;
}
.fps-lbl-name { font-size: 12px; font-weight: 600; }
.fps-lbl-size {
    font-size: 11px;
    fill: var(--fps-muted);
    font-variant-numeric: tabular-nums;
}
/* an item wider than the whole viewport: bar only, no name */
.fps-bar--overrun { stroke-dasharray: 5 4; opacity: 0.45; }
.fps-mark.is-active .fps-bar { stroke: var(--fps-accent); stroke-width: 2; opacity: 1; }
.fps-mark.is-active .fps-lbl-name { fill: var(--fps-accent); }

/* ── tools, top-right of the canvas ──────────────────────────────────────── */
.fps-tools {
    position: absolute;
    top: 8px;
    right: 8px;
    display: flex;
    gap: 4px;
    z-index: 2;
}
.fps-btn {
    display: inline-grid;
    place-items: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 1px solid var(--fps-line);
    border-radius: var(--radius-sm, 0.25rem);
    background: var(--bg-card, #fff);
    color: var(--fps-ink);
    cursor: pointer;
    line-height: 0;
}
.fps-btn:hover { background: var(--hover-bg, rgba(0, 0, 0, 0.06)); }
.fps-btn:focus-visible { outline: 2px solid var(--fps-accent); outline-offset: 1px; }
.fps-btn svg, .fps-btn i { width: 15px; height: 15px; font-size: 13px; }

/* ── scale bar, TOP-left ─────────────────────────────────────────────────
   Top, not bottom: the measure bars and names live along the bottom of the
   canvas, and a scale bar down there collides with them at some zooms. */
.fps-hud {
    --fps-bar: 100px;                     /* set per frame by drawHud() */
    position: absolute;
    left: 10px;
    top: 10px;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 3px 8px 4px;
    border-radius: 999px;
    background: var(--fps-chip);
    font-size: var(--fs-3xs, 0.65rem);
    color: var(--fps-ink);
    pointer-events: none;
    z-index: 2;
}
.fps-hud-bar {
    width: var(--fps-bar);
    max-width: 45vw;
    height: 7px;
    border: 1px solid currentColor;
    border-bottom: 0;
    opacity: 0.75;
}
.fps-hud-label { font-variant-numeric: tabular-nums; font-weight: 600; }
.fps-hud-fov { opacity: 0.75; }

/* ── caption under the canvas ────────────────────────────────────────────── */
.fps-caption {
    border-top: 1px solid var(--fps-line);
    padding: 0.55rem 0.8rem;
    min-height: 3.4rem;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.6rem;
    font-size: var(--fs-sm, 0.85rem);
    line-height: 1.45;
    background: var(--bg-card, #fff);
}
.fps-caption strong { font-weight: 600; }
.fps-cap-note { color: var(--fps-muted); }
.fps-cap-hint { color: var(--fps-muted); font-style: italic; }
.fps-cap-src {
    flex-basis: 100%;
    font-size: var(--fs-3xs, 0.65rem);
    color: var(--fps-muted);
    opacity: 0.85;
}
.fps-cap-times {
    font-size: var(--fs-2xs, 0.72rem);
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    background: var(--bg-body, #f4f6f8);
    border: 1px solid var(--fps-line);
    white-space: nowrap;
}

/* ── full page ───────────────────────────────────────────────────────────
   Surface CSS lives here; the behaviour is FullPage.attach() in the JS. */
body.fps-fullpage { overflow: hidden; }
body.fps-fullpage .fps-widget.fadb-fp-surface {
    position: fixed;
    inset: 0;
    z-index: var(--fadb-fp-z, 900);
    margin: 0;
    border: 0;
    border-radius: 0;
    background: var(--bg-body, #fff);
    display: flex;
    flex-direction: column;
}
body.fps-fullpage .fps-widget.fadb-fp-surface .fps-shell {
    flex: 1;
    min-height: 0;
}
body.fps-fullpage .fps-widget.fadb-fp-surface .fps-canvas-wrap { min-height: 0; }
body.fps-fullpage .fps-widget.fadb-fp-surface .fps-stage { min-height: 0; }
body.fps-fullpage .fps-widget.fadb-fp-surface .fps-canvas { min-height: 0; }
/* In full page the list scrolls after all — the viewport is a hard ceiling
   there, and growing past it is not an option the way it is inline. */
body.fps-fullpage .fps-widget.fadb-fp-surface .fps-list-items { overflow-y: auto; }

/* ── narrow screens: the list moves above the canvas ─────────────────────── */
@media (max-width: 720px) {
    .fps-widget { --fps-h: 380px; }
    .fps-shell { grid-template-columns: minmax(0, 1fr); }
    .fps-list {
        border-right: 0;
        border-bottom: 1px solid var(--fps-line);
    }
    .fps-list-items {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    }
    .fps-row-type { display: none; }
}
