/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */

/* ─── Modern range slider (used by shared/_arrival_filter) ─────────────── */
/* A flat track with no progress fill on either side, and a soft circular
   thumb. Positions are anchors, not magnitudes — so we don't render any
   coloured "gauge" bar. */
.range-slider {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  width: 100%;
  height: 24px;
  cursor: pointer;
  outline: none;
  position: relative; /* sits above the absolutely-positioned SVG wave layer */
}

.range-slider::-webkit-slider-runnable-track {
  height: 4px;
  background: #e5e7eb; /* gray-200 */
  border-radius: 9999px;
}

.range-slider::-moz-range-track {
  height: 4px;
  background: #e5e7eb;
  border-radius: 9999px;
}

/* Firefox draws a filled "progress" segment by default; flatten it. */
.range-slider::-moz-range-progress {
  height: 4px;
  background: #e5e7eb;
  border-radius: 9999px;
}

.range-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  margin-top: -8px;
  border-radius: 9999px;
  background: #ffffff;
  border: 2px solid #4f46e5; /* indigo-600 */
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
  transition: transform 120ms ease, box-shadow 120ms ease;
}

.range-slider::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border-radius: 9999px;
  background: #ffffff;
  border: 2px solid #4f46e5;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
  transition: transform 120ms ease, box-shadow 120ms ease;
}

.range-slider:hover::-webkit-slider-thumb,
.range-slider:focus-visible::-webkit-slider-thumb,
.range-slider:active::-webkit-slider-thumb {
  transform: scale(1.1);
  box-shadow: 0 0 0 6px rgba(79, 70, 229, 0.15);
}

.range-slider:hover::-moz-range-thumb,
.range-slider:focus-visible::-moz-range-thumb,
.range-slider:active::-moz-range-thumb {
  transform: scale(1.1);
  box-shadow: 0 0 0 6px rgba(79, 70, 229, 0.15);
}

/* ─── Sea-themed arrival slider ────────────────────────────────── */
/* Ocean-gradient track, ship/empty-ship/container thumb (--sea-thumb var). */

/* Thumb image tokens — JS sets --sea-thumb on the <input> element inline style;
   the custom property cascades into ::-webkit-slider-thumb via inheritance,
   sidestepping WebKit's compound-class pseudo-element invalidation quirk. */
:root {
  --sea-thumb-ship: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 28'%3E%3Cpath d='M 0,17 L 40,17 L 37,25 L 3,25 Z' fill='%23374151'/%3E%3Crect x='3' y='22' width='34' height='3' fill='%23dc2626'/%3E%3Crect x='0' y='17' width='40' height='1.5' fill='%23e2e8f0'/%3E%3Crect x='2' y='8' width='11' height='9' rx='1' fill='%23e2e8f0'/%3E%3Crect x='3' y='3' width='9' height='6' rx='1' fill='%23cbd5e1'/%3E%3Crect x='4' y='4' width='2' height='2' rx='0.5' fill='%2393c5fd'/%3E%3Crect x='7' y='4' width='2' height='2' rx='0.5' fill='%2393c5fd'/%3E%3Crect x='10' y='4' width='2' height='2' rx='0.5' fill='%2393c5fd'/%3E%3Crect x='5' y='0' width='3' height='4' rx='0.5' fill='%236b7280'/%3E%3Crect x='15' y='12' width='6' height='5' fill='%233b82f6'/%3E%3Crect x='22' y='12' width='6' height='5' fill='%23fbbf24'/%3E%3Crect x='29' y='12' width='6' height='5' fill='%2306b6d4'/%3E%3Crect x='36' y='12' width='4' height='5' fill='%23ef4444'/%3E%3Crect x='15' y='6' width='6' height='6' fill='%23fbbf24'/%3E%3Crect x='22' y='6' width='6' height='6' fill='%2306b6d4'/%3E%3Crect x='29' y='6' width='6' height='6' fill='%23ef4444'/%3E%3Crect x='36' y='6' width='4' height='6' fill='%233b82f6'/%3E%3Crect x='15' y='0' width='6' height='6' fill='%2306b6d4'/%3E%3Crect x='22' y='0' width='6' height='6' fill='%23ef4444'/%3E%3Crect x='29' y='0' width='6' height='6' fill='%233b82f6'/%3E%3Crect x='36' y='0' width='4' height='6' fill='%23fbbf24'/%3E%3C/svg%3E");
  --sea-thumb-empty-ship: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 28'%3E%3Cpath d='M 0,17 L 40,17 L 37,25 L 3,25 Z' fill='%23374151'/%3E%3Crect x='3' y='22' width='34' height='3' fill='%23dc2626'/%3E%3Crect x='0' y='17' width='40' height='1.5' fill='%23e2e8f0'/%3E%3Crect x='2' y='8' width='11' height='9' rx='1' fill='%23e2e8f0'/%3E%3Crect x='3' y='3' width='9' height='6' rx='1' fill='%23cbd5e1'/%3E%3Crect x='4' y='4' width='2' height='2' rx='0.5' fill='%2393c5fd'/%3E%3Crect x='7' y='4' width='2' height='2' rx='0.5' fill='%2393c5fd'/%3E%3Crect x='10' y='4' width='2' height='2' rx='0.5' fill='%2393c5fd'/%3E%3Crect x='5' y='0' width='3' height='4' rx='0.5' fill='%236b7280'/%3E%3Crect x='14' y='10' width='24' height='7' rx='0.5' fill='%234b5563'/%3E%3Cline x1='14' y1='13' x2='38' y2='13' stroke='%236b7280' stroke-width='1'/%3E%3Cline x1='20' y1='10' x2='20' y2='17' stroke='%236b7280' stroke-width='0.5'/%3E%3Cline x1='26' y1='10' x2='26' y2='17' stroke='%236b7280' stroke-width='0.5'/%3E%3Cline x1='32' y1='10' x2='32' y2='17' stroke='%236b7280' stroke-width='0.5'/%3E%3C/svg%3E");
  --sea-thumb-container: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 28'%3E%3Crect x='2' y='5' width='36' height='18' rx='1' fill='%231d4ed8'/%3E%3Crect x='2' y='5' width='36' height='4' rx='1' fill='%233b82f6'/%3E%3Crect x='2' y='19' width='36' height='4' rx='1' fill='%231e3a8a'/%3E%3Cline x1='10' y1='6' x2='10' y2='22' stroke='%231e40af' stroke-width='1'/%3E%3Cline x1='20' y1='6' x2='20' y2='22' stroke='%231e40af' stroke-width='1'/%3E%3Cline x1='30' y1='6' x2='30' y2='22' stroke='%231e40af' stroke-width='1'/%3E%3Crect x='32' y='9' width='2' height='8' rx='0.5' fill='%2393c5fd'/%3E%3Crect x='35' y='9' width='2' height='8' rx='0.5' fill='%2393c5fd'/%3E%3Crect x='2' y='5' width='4' height='4' rx='0.5' fill='%231e40af'/%3E%3Crect x='34' y='5' width='4' height='4' rx='0.5' fill='%231e40af'/%3E%3Crect x='2' y='19' width='4' height='4' rx='0.5' fill='%231e40af'/%3E%3Crect x='34' y='19' width='4' height='4' rx='0.5' fill='%231e40af'/%3E%3C/svg%3E");
}

.sea-slider::-webkit-slider-runnable-track {
  height: 6px;
  background: transparent; /* SVG wave layer provides the visual track */
  border-radius: 9999px;
}

.sea-slider::-moz-range-track {
  height: 6px;
  background: transparent;
  border-radius: 9999px;
}

.sea-slider::-moz-range-progress {
  height: 0;
}

.sea-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 40px;
  height: 28px;
  margin-top: -11px;
  border-radius: 0;
  background-color: transparent;
  background-image: var(--sea-thumb, var(--sea-thumb-ship));
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  border: none;
  box-shadow: none;
  cursor: grab;
  transition: transform 120ms ease;
}

.sea-slider::-moz-range-thumb {
  width: 40px;
  height: 28px;
  border-radius: 0;
  background-color: transparent;
  background-image: var(--sea-thumb, var(--sea-thumb-ship));
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  border: none;
  box-shadow: none;
  cursor: grab;
  transition: transform 120ms ease;
}

.sea-slider:hover::-webkit-slider-thumb,
.sea-slider:focus-visible::-webkit-slider-thumb,
.sea-slider:active::-webkit-slider-thumb {
  transform: scale(1.15);
  box-shadow: none;
}

/* ─── Arrival slider waypoint tooltips ─────────────────────────── */
.sea-tip {
  cursor: default;
}

.sea-tip::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  padding: 5px 9px;
  background: #1f2937;
  color: #f9fafb;
  font-size: 11px;
  line-height: 1.5;
  border-radius: 5px;
  width: max-content;
  max-width: 210px;
  white-space: normal;
  pointer-events: none;
  opacity: 0;
  transition: opacity 150ms ease;
  z-index: 30;
}

.sea-tip:hover::after {
  opacity: 1;
}
/* ─── Packing table "Edit values" mode ─────────────────────────────────── */
/* While editing is active, editable cells show a text cursor and a soft
   hover highlight. Edited cells are indicated via a hover tooltip, not a
   persistent marker. */
.packing-editing .packing-cell {
  cursor: text;
}

.packing-editing .packing-cell:hover {
  background-color: #eff6ff; /* blue-50 */
}

/* A total the validation flags as inconsistent (box count or net weight) gets a
   red wavy underline, like a spell-check error, until it is resolved. */
.total-flagged {
  text-decoration: underline;
  text-decoration-style: wavy;
  text-decoration-color: #dc2626; /* red-600 */
  text-underline-offset: 4px;
  text-decoration-thickness: 1.5px;
}

/* ─── Trade lane route maps ────────────────────────────────────────────── */
/* Drawn by `rake learn:lane_maps` into app/assets/images/learn/lanes/*.svg and
   inlined by LaneMapComponent. The generated SVG carries classes and no
   colours, so the whole palette — light and dark — lives here rather than in
   fifteen files that would have to be redrawn to be restyled. */
.lane-map {
  display: block;
  width: 100%;
  height: auto;
}

.lane-map__sea { fill: #eff5fb; }
.lane-map__land { fill: #dde5ee; }
.lane-map__grid { stroke: #cbd5e1; stroke-width: 0.75; opacity: 0.5; }
.lane-map__equator { stroke: #94a3b8; stroke-width: 0.75; stroke-dasharray: 5 5; opacity: 0.7; }

.lane-map__route {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.lane-map__route--main { stroke: #4f46e5; stroke-width: 3.5; }

/* A second route that is every bit as real as the first: two lanes compared on
   one map, rather than one lane and its contingency. It has to be solid, because
   this hub has already taught readers that dashed means "sometimes" — the guide
   maps use --alt for a passage nobody sails any more, and a live trade drawn the
   same way would inherit that meaning. Teal is dark enough not to be confused
   with the wind ribbons, which are the same family of hue at a fifth the weight. */
.lane-map__route--second { stroke: #0f766e; stroke-width: 3.5; }

/* The alternative routing is dashed and quieter. It is a thing that sometimes
   happens, not a second answer to "how does my fruit get here". */
.lane-map__route--alt {
  stroke: #94a3b8;
  stroke-width: 2.5;
  stroke-dasharray: 9 7;
}

/* A prevailing wind belt, drawn as a wide translucent ribbon along the belt's
   axis rather than as a filled band between two latitudes. The renderer draws
   lines, not areas — but the honest reason to keep it a ribbon is that these
   belts have no edges. They shift with the season and shade into each other,
   and a hard boundary would claim a precision the atmosphere does not have.
   Sky rather than indigo or amber: it must not read as a route or a road. */
.lane-map__route--wind {
  stroke: #0ea5e9;
  stroke-width: 22;
  opacity: 0.2;
}

/* The leg that is not a voyage. Amber because it is the part of the journey
   this panel is warning about, and dashed because a lorry route is a direction
   rather than a track — we know the box goes inland, not which road it takes. */
.lane-map__route--land {
  stroke: #d97706;
  stroke-width: 5;
  stroke-dasharray: 2 11;
}

/* A port is a place the ship stops, and is filled in; a chokepoint is a place
   it passes through, and is left hollow. An inland place is neither, and is
   square — no ship reaches it. */
.lane-map__mark--port .lane-map__pin { fill: #4f46e5; stroke: #ffffff; stroke-width: 2; }
.lane-map__mark--chokepoint .lane-map__pin { stroke: #4f46e5; stroke-width: 2.5; }
.lane-map__mark--inland .lane-map__pin { fill: #d97706; stroke: #ffffff; stroke-width: 2; }

/* A label with no marker under it names a region of ocean. It is set lighter
   than a port name so that the two do not read as the same kind of fact: one
   is a place with a quay, the other is roughly where the wind blows. */
.lane-map__mark--label text { fill: #0369a1; font-weight: 500; }

.lane-map__leader { stroke: #94a3b8; stroke-width: 1; fill: none; }

/* The halo is the sea colour rather than white, so a label crossing a
   coastline stays readable without punching a hole in the map. */
.lane-map__mark text {
  fill: #1f2937;
  stroke: #eff5fb;
  stroke-width: 3.5;
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-weight: 600;
}

/* Hovering a marker is the whole of the interaction: the dot grows, the rest
   of them step back, and the browser shows the title element the SVG already
   carries — which is the same text a screen reader reads. */
.lane-map__mark { transition: opacity 120ms ease; }
.lane-map__mark .lane-map__pin { transition: r 120ms ease; }
.lane-map__mark:hover .lane-map__pin { r: 7.5; }
.lane-map:hover .lane-map__mark:not(:hover) { opacity: 0.5; }

/* A hazard panel is drawn at the same 1000-unit width as a route map and shown
   at half the size, so every stroke in it has to be about twice as heavy to
   survive the reduction — including the one that grows on hover, which at the
   full-size figure would be smaller than the dot it replaces. */
.lane-map--panel .lane-map__route--main { stroke-width: 6; }
.lane-map--panel .lane-map__route--land { stroke-width: 8; stroke-dasharray: 3 17; }
.lane-map--panel .lane-map__grid { stroke-width: 1.25; }
.lane-map--panel .lane-map__mark text { stroke-width: 6; }
.lane-map--panel .lane-map__mark--port .lane-map__pin,
.lane-map--panel .lane-map__mark--inland .lane-map__pin { stroke-width: 3; }
.lane-map--panel .lane-map__mark--chokepoint .lane-map__pin { stroke-width: 4; }
.lane-map--panel .lane-map__leader { stroke-width: 1.75; }
.lane-map--panel .lane-map__mark:hover .lane-map__pin { r: 11; }

.dark .lane-map__sea { fill: #0b1120; }
.dark .lane-map__land { fill: #1e293b; }
.dark .lane-map__grid { stroke: #334155; opacity: 0.6; }
.dark .lane-map__equator { stroke: #475569; }
.dark .lane-map__route--main { stroke: #818cf8; }
.dark .lane-map__route--alt { stroke: #64748b; }
.dark .lane-map__route--land { stroke: #fbbf24; }
.dark .lane-map__mark--port .lane-map__pin { fill: #818cf8; stroke: #0b1120; }
.dark .lane-map__mark--chokepoint .lane-map__pin { stroke: #a5b4fc; }
.dark .lane-map__mark--inland .lane-map__pin { fill: #fbbf24; stroke: #0b1120; }
.dark .lane-map__route--wind { stroke: #38bdf8; opacity: 0.26; }
.dark .lane-map__route--second { stroke: #5eead4; }
.dark .lane-map__mark--label text { fill: #7dd3fc; }
.dark .lane-map__leader { stroke: #64748b; }
.dark .lane-map__mark text { fill: #e2e8f0; stroke: #0b1120; }


/* ═══ Guide figures ══════════════════════════════════════════════════════════
   A diagram imported from a Claude Design project by
   script/import_design_figure.py. Everything down to the FIGURE-SPECIFIC
   heading at the bottom is generic: a second figure needs no CSS at all,
   provided its markup comes out of that script.

   Editorial guidance is in docs/AUTHORING.md under "Adapting a design
   project"; what follows is the styling half.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Palette ──
   The hub's own neutrals, not the design's warm cream. That one substitution is
   most of what stops an imported figure looking pasted in from somewhere else.
   Only the three signal hues carry over, because those mean something. */
.docs-prose .guide-figure {
  --fig-ink: rgb(17 24 39);
  --fig-ink-55: rgb(17 24 39 / 0.55);
  --fig-ink-50: rgb(17 24 39 / 0.5);
  --fig-ink-45: rgb(17 24 39 / 0.45);
  --fig-ink-35: rgb(17 24 39 / 0.35);
  --fig-ink-20: rgb(17 24 39 / 0.2);
  --fig-ink-18: rgb(17 24 39 / 0.18);
  --fig-ink-16: rgb(17 24 39 / 0.16);
  --fig-ink-12: rgb(17 24 39 / 0.12);
  --fig-ink-10: rgb(17 24 39 / 0.1);
  --fig-ink-075: rgb(17 24 39 / 0.075);
  --fig-ink-07: rgb(17 24 39 / 0.07);
  --fig-paper: rgb(255 255 255);
  --fig-paper-50: rgb(255 255 255 / 0.5);
  --fig-paper-2: rgb(249 250 251);
  --fig-body: rgb(75 85 99);
  --fig-dim: rgb(107 114 128);
  --fig-cold: rgb(37 99 235);
  --fig-warm: rgb(194 91 42);
  --fig-alert: rgb(190 60 48);

  margin: 1.75rem 0 2rem;
}

.dark .docs-prose .guide-figure {
  --fig-ink: rgb(229 231 235);
  --fig-ink-55: rgb(229 231 235 / 0.55);
  --fig-ink-50: rgb(229 231 235 / 0.5);
  --fig-ink-45: rgb(229 231 235 / 0.45);
  --fig-ink-35: rgb(229 231 235 / 0.35);
  --fig-ink-20: rgb(229 231 235 / 0.22);
  --fig-ink-18: rgb(229 231 235 / 0.2);
  --fig-ink-16: rgb(229 231 235 / 0.18);
  --fig-ink-12: rgb(229 231 235 / 0.14);
  --fig-ink-10: rgb(229 231 235 / 0.12);
  --fig-ink-075: rgb(229 231 235 / 0.09);
  --fig-ink-07: rgb(229 231 235 / 0.08);
  --fig-paper: rgb(17 24 39);
  --fig-paper-50: rgb(17 24 39 / 0.5);
  --fig-paper-2: rgb(31 41 55);
  --fig-body: rgb(156 163 175);
  --fig-dim: rgb(156 163 175);
  --fig-cold: rgb(96 165 250);
  --fig-warm: rgb(251 146 60);
  --fig-alert: rgb(248 113 113);
}

/* ── Scaling ──
   These drawings are absolutely-positioned parts on a fixed canvas, so they
   cannot reflow — but they can be scaled as one picture. The figure declares
   its canvas as --fig-w / --fig-h; the stage is a query container and the
   canvas is scaled by the ratio of the two widths, so the whole drawing is
   visible at whatever the column happens to be.

   Do not reach for horizontal scroll here. It was the first answer and it was
   wrong: a diagram cut in half with a scrollbar under it does not read as
   "drag me", it reads as broken. */
.docs-prose .guide-figure__stage {
  container-type: inline-size;
  overflow: hidden;
}

.docs-prose .guide-figure__stage > div {
  transform-origin: top left;
}

@supports (width: 1cqw) {
  .docs-prose .guide-figure__stage {
    aspect-ratio: var(--fig-w) / var(--fig-h);
  }

  .docs-prose .guide-figure__stage > div {
    transform: scale(calc(100cqw / (var(--fig-w) * 1px)));
  }
}

@supports not (width: 1cqw) {
  .docs-prose .guide-figure__stage {
    overflow-x: auto;
  }
}

/* ── The key ──
   Text, so it reflows on its own rather than scaling with the picture. */
.docs-prose .guide-figure__key > div {
  display: grid;
  grid-template-columns: repeat(3, 1fr) !important;
  gap: 1px !important;
  margin-top: 1.5rem !important;
  background: var(--fig-ink-12) !important;
  border: 1px solid var(--fig-ink-12) !important;
  border-radius: 0.5rem;
  overflow: hidden;
}

@media (max-width: 60rem) {
  .docs-prose .guide-figure__key > div { grid-template-columns: repeat(2, 1fr) !important; }
}

@media (max-width: 34rem) {
  .docs-prose .guide-figure__key > div { grid-template-columns: 1fr !important; }
}

.docs-prose .guide-figure__part {
  transition: background-color 0.25s ease;
  color: var(--fig-ink);
}

.docs-prose .guide-figure__part p { color: var(--fig-body); }

.docs-prose .guide-figure__part:hover {
  background: color-mix(in srgb, var(--fig-cold) 6%, var(--fig-paper-2)) !important;
}

/* ── Selecting a part ──
   A radio group, not links into the key. Links failed twice over: an <a> around
   an absolutely-positioned child has no box of its own, so clicking the middle
   of a dot did nothing, and following a fragment scrolled the diagram off
   screen to reveal the card. A radio changes no URL and a <label> is a real box
   that can be made big enough to hit. No JavaScript, and the group is arrow-key
   navigable for free.

   Ids are figure-agnostic (figpart-N) so these rules are written once and every
   later figure inherits them. The cost is one interactive figure per page,
   since ids must be unique — enforced by test/models/learn/guide_figure_test.rb. */
.docs-prose .guide-figure__radio {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.docs-prose .guide-figure__callout,
.docs-prose .guide-figure__jump,
.docs-prose .guide-figure__cover {
  cursor: pointer;
}

/* The drawing is scaled down, so a 24px dot can land at 14 real pixels — far
   too small to hit. The label is padded past the dot in the drawing's own
   coordinates, so the target survives the scaling. */
.docs-prose .guide-figure__callout {
  display: block;
  padding: 12px;
  margin: -12px;
  border-radius: 50%;
}

/* The whole card selects its part, not just the badge. A <label> may not wrap a
   <p>, so it is stretched over the card instead. */
.docs-prose .guide-figure__cover {
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.docs-prose .guide-figure__callout > span,
.docs-prose .guide-figure__jump > span {
  transition: background-color 0.15s ease, box-shadow 0.15s ease;
}

.docs-prose .guide-figure__callout:hover > span,
.docs-prose .guide-figure__jump:hover > span {
  background: var(--fig-cold) !important;
}

/* Each part highlights in three places at once, from the one checked radio: its
   number on the drawing, the part itself, and its card in the key. There is a
   rule per part because no selector can carry the matched number across to the
   thing it should highlight. Written to 12 so a bigger figure needs no CSS. */
.docs-prose .guide-figure:has(#figpart-1:checked) .guide-figure__callout[for="figpart-1"] > span,
.docs-prose .guide-figure:has(#figpart-2:checked) .guide-figure__callout[for="figpart-2"] > span,
.docs-prose .guide-figure:has(#figpart-3:checked) .guide-figure__callout[for="figpart-3"] > span,
.docs-prose .guide-figure:has(#figpart-4:checked) .guide-figure__callout[for="figpart-4"] > span,
.docs-prose .guide-figure:has(#figpart-5:checked) .guide-figure__callout[for="figpart-5"] > span,
.docs-prose .guide-figure:has(#figpart-6:checked) .guide-figure__callout[for="figpart-6"] > span,
.docs-prose .guide-figure:has(#figpart-7:checked) .guide-figure__callout[for="figpart-7"] > span,
.docs-prose .guide-figure:has(#figpart-8:checked) .guide-figure__callout[for="figpart-8"] > span,
.docs-prose .guide-figure:has(#figpart-9:checked) .guide-figure__callout[for="figpart-9"] > span,
.docs-prose .guide-figure:has(#figpart-10:checked) .guide-figure__callout[for="figpart-10"] > span,
.docs-prose .guide-figure:has(#figpart-11:checked) .guide-figure__callout[for="figpart-11"] > span,
.docs-prose .guide-figure:has(#figpart-12:checked) .guide-figure__callout[for="figpart-12"] > span {
  background: var(--fig-cold) !important;
  color: var(--fig-paper) !important;
  box-shadow: 0 0 0 3px var(--fig-cold), 0 0 0 6px var(--fig-paper);
}

.docs-prose .guide-figure:has(#figpart-1:checked) .guide-figure__part[data-part="1"],
.docs-prose .guide-figure:has(#figpart-2:checked) .guide-figure__part[data-part="2"],
.docs-prose .guide-figure:has(#figpart-3:checked) .guide-figure__part[data-part="3"],
.docs-prose .guide-figure:has(#figpart-4:checked) .guide-figure__part[data-part="4"],
.docs-prose .guide-figure:has(#figpart-5:checked) .guide-figure__part[data-part="5"],
.docs-prose .guide-figure:has(#figpart-6:checked) .guide-figure__part[data-part="6"],
.docs-prose .guide-figure:has(#figpart-7:checked) .guide-figure__part[data-part="7"],
.docs-prose .guide-figure:has(#figpart-8:checked) .guide-figure__part[data-part="8"],
.docs-prose .guide-figure:has(#figpart-9:checked) .guide-figure__part[data-part="9"],
.docs-prose .guide-figure:has(#figpart-10:checked) .guide-figure__part[data-part="10"],
.docs-prose .guide-figure:has(#figpart-11:checked) .guide-figure__part[data-part="11"],
.docs-prose .guide-figure:has(#figpart-12:checked) .guide-figure__part[data-part="12"] {
  background: color-mix(in srgb, var(--fig-cold) 14%, var(--fig-paper-2)) !important;
  box-shadow: inset 3px 0 0 var(--fig-cold);
}

/* The drawing is anonymous positioned boxes with nothing to hang a highlight
   on, so each part has a region drawn over it, invisible until it is chosen. */
.docs-prose .guide-figure__region {
  position: absolute;
  display: block;
  pointer-events: none;
  border-radius: 6px;
  opacity: 0;
  background: color-mix(in srgb, var(--fig-cold) 16%, transparent);
  box-shadow: 0 0 0 2px var(--fig-cold);
  transition: opacity 0.18s ease;
}

.docs-prose .guide-figure:has(#figpart-1:checked) .guide-figure__region[data-part="1"],
.docs-prose .guide-figure:has(#figpart-2:checked) .guide-figure__region[data-part="2"],
.docs-prose .guide-figure:has(#figpart-3:checked) .guide-figure__region[data-part="3"],
.docs-prose .guide-figure:has(#figpart-4:checked) .guide-figure__region[data-part="4"],
.docs-prose .guide-figure:has(#figpart-5:checked) .guide-figure__region[data-part="5"],
.docs-prose .guide-figure:has(#figpart-6:checked) .guide-figure__region[data-part="6"],
.docs-prose .guide-figure:has(#figpart-7:checked) .guide-figure__region[data-part="7"],
.docs-prose .guide-figure:has(#figpart-8:checked) .guide-figure__region[data-part="8"],
.docs-prose .guide-figure:has(#figpart-9:checked) .guide-figure__region[data-part="9"],
.docs-prose .guide-figure:has(#figpart-10:checked) .guide-figure__region[data-part="10"],
.docs-prose .guide-figure:has(#figpart-11:checked) .guide-figure__region[data-part="11"],
.docs-prose .guide-figure:has(#figpart-12:checked) .guide-figure__region[data-part="12"] {
  opacity: 1;
}

.docs-prose .guide-figure figcaption {
  margin-top: 0.85rem;
  font-size: 0.8125rem;
  line-height: 1.55;
  color: rgb(107 114 128);
}

.dark .docs-prose .guide-figure figcaption { color: rgb(156 163 175); }

@media (prefers-reduced-motion: reduce) {
  .docs-prose .guide-figure * { animation: none !important; }
}

/* ── FIGURE-SPECIFIC ──────────────────────────────────────────────────────
   Everything above is generic. What follows belongs to one figure each, and a
   new import should add to this section rather than change anything above it.
   ───────────────────────────────────────────────────────────────────────── */

/* reefer-container-technology: the controller readout is the one panel drawn on
   ink rather than paper, so it inverts with the theme — its accents need
   re-darkening on the light panel it becomes. It also grows to its content,
   because the system mono stack sets taller than the webfont the design was
   measured against. */
.docs-prose .guide-figure__readout {
  height: auto !important;
  min-height: 72px;
}

.dark .docs-prose .guide-figure__readout {
  --fig-cold: rgb(29 78 216);
  --fig-warm: rgb(154 52 18);
}

/* reefer-container-technology: the export animates its airflow dashes, and the
   keyframes lived in the design's own page head — which is not the part the
   importer copies, so they have to be declared here or the arrows sit still. */
@keyframes flowDash {
  to { stroke-dashoffset: -66; }
}

/* wind-assisted-shipping-fresh-produce: this drawing is a single <svg> rather
   than positioned boxes, so the regions the importer writes ahead of it are
   painted over by the hulls instead of showing through the gaps between them.
   Lifting them one layer is the whole fix, and it is scoped to this figure
   because the box-drawn one reads better with the highlight underneath. */
.docs-prose .guide-figure:has(input[name="wind-assisted-shipping-fresh-produce-part"]) .guide-figure__region {
  z-index: 1;
}

/* wind-assisted-shipping-fresh-produce: the export turns the rotors and lets
   the kite ride, and its keyframes lived in the design's page head, which the
   importer does not copy. Both are declared on classes the export carries
   through; the reduced-motion rule above stops them.

   The rotors' arrows spin about a point on the drawing rather than their own
   centre, so the export sets transform-origin inline per rotor and this only
   provides the default and the box it is measured in. */
.docs-prose .guide-figure .wa-spin {
  transform-origin: center;
  transform-box: fill-box;
  animation: rotorSpinTurn 3.4s linear infinite;
}

.docs-prose .guide-figure .wa-kite {
  animation: kiteDriftBob 4.2s ease-in-out infinite;
}

@keyframes rotorSpinTurn {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

@keyframes kiteDriftBob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-8px); }
}
