/* Lucid — one stylesheet for every custom admin screen.

   Loaded through UNFOLD["STYLES"] so it applies to the dashboard, the plan
   cockpit and the report pages alike; previously each template carried its own
   <style> block and the dashboard silently missed half of them.

   Two things to know before editing:

   1. Unfold ships Tailwind v4, whose theme variables hold COMPLETE colour
      values — `--color-base-200` is `oklch(92.8% .006 264.531)`, not the bare
      "R G B" triplet Tailwind v3 used. So write `var(--color-base-200)`, never
      `rgb(var(--color-base-200))`: the latter expands to `rgb(oklch(...))`,
      which is invalid, and the whole declaration is dropped — which is exactly
      how the buttons ended up with no background. For translucency use
      `color-mix(in oklab, var(--x) 15%, transparent)`.

   2. Unfold's bundle only contains the Tailwind utilities Unfold itself uses.
      Anything else we reference has to be defined here (see "missing
      utilities" at the bottom) — there is no Tailwind build in this project
      and deliberately so: one hand-written stylesheet is easier to reason
      about than a build step for a dozen screens.
*/

:root {
/* Complete colour values, matching how Unfold's own variables are written.
     Bare "R G B" triplets only work inside rgb(), and nothing here uses that
     form any more. */
--lucid-danger: rgb(220 38 38);
--lucid-warn:   rgb(217 119 6);
--lucid-ok:     rgb(22 163 74);
--lucid-info:   rgb(37 99 235);
}
.dark {
/* Lifted for contrast against a dark background. */
--lucid-danger: rgb(248 113 113);
--lucid-warn:   rgb(251 191 36);
--lucid-ok:     rgb(74 222 128);
--lucid-info:   rgb(96 165 250);
}

.lucid-card {
    border: 1px solid var(--color-base-200);
    border-radius: .5rem;
    padding: 1.25rem;
    background: var(--color-base-50);
}
.dark .lucid-card { border-color: var(--color-base-800); background: var(--color-base-900); }

.lucid-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 1rem; }
.lucid-metric { font-size: 1.6rem; font-weight: 600; line-height: 1.2; }
.lucid-label { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; opacity: .6; }
.lucid-danger { color: var(--lucid-danger); }
.lucid-warn   { color: var(--lucid-warn); }
.lucid-ok     { color: var(--lucid-ok); }

/* ---- filter bar: match Unfold's form controls -------------------- */
.lucid-bar { display: flex; flex-wrap: wrap; gap: .75rem; align-items: flex-end; margin-bottom: 1.25rem; }
.lucid-bar label { display: block; font-size: .72rem; opacity: .7; margin-bottom: .25rem; }
.lucid-bar input[type="date"],
.lucid-bar input[type="number"],
.lucid-bar input[type="text"],
.lucid-select {
    appearance: none;
    border: 1px solid var(--color-base-200);
    background: var(--color-base-50);
    color: var(--color-font-default-light);
    border-radius: .375rem;
    padding: .45rem 2rem .45rem .65rem;
    font-size: .8125rem;
    line-height: 1.25rem;
    min-width: 9rem;
    box-shadow: 0 1px 2px rgb(0 0 0 / .04);
}
.dark .lucid-bar input[type="date"],
.dark .lucid-bar input[type="number"],
.dark .lucid-bar input[type="text"],
.dark .lucid-select {
    border-color: var(--color-base-700);
    background: var(--color-base-900);
    color: var(--color-font-default-dark);
}
.lucid-select {
    /* Unfold's chevron, inlined so no external asset is needed. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%239ca3af' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M19 9l-7 7-7-7'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .5rem center;
    background-size: 1.1em;
}
.lucid-select:focus,
.lucid-bar input:focus {
    outline: 2px solid color-mix(in oklab, var(--color-primary-500) 45%, transparent);
    outline-offset: 1px;
    border-color: var(--color-primary-500);
}

/* Inputs inside tables and cards (the cockpit grid) get the same treatment
     as the filter bar — otherwise the editable columns look like raw HTML. */
.lucid-table input,
.lucid-card input:not([type="checkbox"]):not([type="radio"]) {
    border: 1px solid var(--color-base-200);
    background: var(--color-base-50);
    color: var(--color-font-default-light);
    border-radius: .375rem;
    padding: .35rem .55rem;
    font-size: .8125rem;
}
.dark .lucid-table input,
.dark .lucid-card input:not([type="checkbox"]):not([type="radio"]) {
    border-color: var(--color-base-700);
    background: var(--color-base-950);
    color: var(--color-font-default-dark);
}
.lucid-table input:focus,
.lucid-card input:focus {
    outline: 2px solid color-mix(in oklab, var(--color-primary-500) 45%, transparent);
    outline-offset: 1px;
    border-color: var(--color-primary-500);
}
/* The number a user is actively deciding should look decided. */
.lucid-table input.js-qty { font-weight: 600; }

.lucid-btn {
    background: var(--color-primary-600);
    color: #fff; padding: .5rem .9rem; border-radius: .375rem;
    font-weight: 500; font-size: .8125rem; border: 0; cursor: pointer;
}
.lucid-btn:hover { background: var(--color-primary-700); }
.lucid-btn-ghost {
    border: 1px solid var(--color-base-200);
    padding: .45rem .8rem; border-radius: .375rem; font-size: .8125rem;
}
.dark .lucid-btn-ghost { border-color: var(--color-base-700); }
.lucid-btn-ghost:hover { border-color: var(--color-primary-500); }

/* ---- tables ------------------------------------------------------ */
.lucid-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.lucid-table th {
    text-align: left; font-size: .68rem; text-transform: uppercase;
    letter-spacing: .04em; opacity: .6; padding: .5rem .6rem; font-weight: 600;
}
.lucid-table td { padding: .55rem .6rem; border-top: 1px solid var(--color-base-200); }
.dark .lucid-table td { border-color: var(--color-base-800); }
.lucid-table tbody tr:hover td { background: color-mix(in oklab, var(--color-base-100) 60%, transparent); }
.dark .lucid-table tbody tr:hover td { background: color-mix(in oklab, var(--color-base-800) 40%, transparent); }
.lucid-scroll { overflow-x: auto; }

/* ---- status pills ------------------------------------------------ */
.lucid-pill {
    display: inline-block; padding: .1rem .5rem; border-radius: 999px;
    font-size: .68rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em;
}
.lucid-pill-short { background: color-mix(in oklab, var(--lucid-danger) 15%, transparent); color: var(--lucid-danger); }
.lucid-pill-late  { background: color-mix(in oklab, var(--lucid-warn) 18%, transparent);  color: var(--lucid-warn); }
.lucid-pill-over  { background: color-mix(in oklab, var(--lucid-info) 15%, transparent);  color: var(--lucid-info); }
.lucid-pill-ok    { background: color-mix(in oklab, var(--lucid-ok) 15%, transparent);    color: var(--lucid-ok); }
/* Severity aliases, for pills whose subject is not a coverage verdict. */
.lucid-pill-bad   { background: color-mix(in oklab, var(--lucid-danger) 15%, transparent); color: var(--lucid-danger); }
.lucid-pill-warn  { background: color-mix(in oklab, var(--lucid-warn) 18%, transparent);   color: var(--lucid-warn); }
.lucid-pill-good  { background: color-mix(in oklab, var(--lucid-ok) 15%, transparent);     color: var(--lucid-ok); }

/* ---- utilities Unfold's bundle does not ship -------------------------------
   Used across the custom templates for visual hierarchy. Without them every
   caption renders at full strength and the hierarchy collapses. */
.opacity-40 { opacity: .4; }
.opacity-60 { opacity: .6; }
.opacity-70 { opacity: .7; }
.opacity-80 { opacity: .8; }
.tracking-wide { letter-spacing: .025em; }

/* ---- dashboard ----------------------------------------------------------- */
.lucid-dash-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(205px, 1fr)); gap: 1rem; }
.lucid-panel {
border: 1px solid var(--color-base-200);
border-radius: .5rem;
padding: 1.25rem;
background: var(--color-base-50);
}
.dark .lucid-panel { border-color: var(--color-base-800); background: var(--color-base-900); }

/* A panel title on the left and its verdict on the right. The verdict is the
   part people read first, so it gets the end of the line, not a footnote. */
.lucid-panel-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: .5rem;
}
.lucid-cash-headline { font-size: .8125rem; font-weight: 600; }


/* ---- plan cockpit --------------------------------------------------------- */
/* The product name is printed once per group; a rule marks where the next
   garment starts, so sixty editable rows still read as twenty things. */
.lucid-table tr.is-group-start td { border-top: 1px solid var(--color-base-300); }
.dark .lucid-table tr.is-group-start td { border-top-color: var(--color-base-700); }
.lucid-est {
font-size: .6rem; text-transform: uppercase; letter-spacing: .04em;
opacity: .55; margin-left: .3rem;
}

/* ---- period bar & tabs ---------------------------------------------------- */
.lucid-periodbar {
padding: .75rem 1rem;
border: 1px solid var(--color-base-200);
border-radius: .5rem;
background: var(--color-base-50);
}
.dark .lucid-periodbar { border-color: var(--color-base-800); background: var(--color-base-900); }

.lucid-tabs { display: flex; gap: .25rem; margin-bottom: 1.25rem; flex-wrap: wrap; }
.lucid-tab {
padding: .45rem .9rem;
border-radius: .375rem;
font-size: .8125rem;
font-weight: 500;
border: 1px solid transparent;
color: inherit;
}
.lucid-tab:hover { background: color-mix(in oklab, var(--color-base-500) 10%, transparent); }
.lucid-tab.is-active {
background: var(--color-primary-600);
color: #fff;
}

/* ---- "needs a decision" list ---------------------------------------------
   The dashboard's first block. Rows are links, because every item here is
   something you go and do; a dot carries the severity so the list can be
   scanned without reading. */
.lucid-attention { display: flex; flex-direction: column; }
.lucid-attention-row {
  display: flex; align-items: center; gap: .75rem;
  padding: .7rem .25rem;
  border-top: 1px solid var(--color-base-200);
  color: inherit;
}
.dark .lucid-attention-row { border-top-color: var(--color-base-800); }
.lucid-attention-row:first-child { border-top: 0; }
.lucid-attention-row:hover { background: color-mix(in oklab, var(--color-base-500) 8%, transparent); }
.lucid-attention-dot { width: .5rem; height: .5rem; border-radius: 999px; flex: none; }
.lucid-attention-row.is-critical .lucid-attention-dot { background: var(--lucid-danger); }
.lucid-attention-row.is-warning  .lucid-attention-dot { background: var(--lucid-warn); }
.lucid-attention-row.is-info     .lucid-attention-dot { background: var(--lucid-info); }
.lucid-attention-text { flex: 1; font-size: .875rem; display: flex; gap: .5rem; flex-wrap: wrap; }
.lucid-attention-action { font-size: .8125rem; opacity: .7; white-space: nowrap; }
.lucid-attention-row:hover .lucid-attention-action { opacity: 1; }

/* The reasoning behind each suggestion, visible rather than hover-only —
   it is the thing that makes a proposed number trustworthy. */
.lucid-basis {
  font-size: .68rem;
  line-height: 1.25;
  opacity: .6;
  max-width: 16rem;
  margin-left: auto;
  text-align: right;
  margin-top: .15rem;
}

.lucid-unit { font-size: .8rem; font-weight: 400; opacity: .55; }
/* Something went wrong, or there is nothing yet — either way, say so and give
   somewhere to go. A blank chart frame reads as "all clear". */
.lucid-empty {
  display: flex; align-items: center; justify-content: center; gap: .4rem;
  height: 100%; min-height: 5rem; font-size: .85rem; opacity: .75; text-align: center;
}

/* ---- chart legend --------------------------------------------------------
   A Gantt whose colours are only explained in JavaScript is a puzzle. */
.lucid-legend { display: flex; gap: 1rem; flex-wrap: wrap; margin-top: .75rem; font-size: .75rem; opacity: .8; }
.lucid-legend span { display: inline-flex; align-items: center; gap: .35rem; }
.lucid-swatch { width: 1.1rem; height: .5rem; border-radius: 2px; display: inline-block; }
.lucid-swatch[data-status="ordered"]   { background: #d97706; }
.dark .lucid-swatch[data-status="ordered"] { background: #fbbf24; }
.lucid-swatch[data-status="received"]  { background: var(--lucid-ok); }
.lucid-swatch[data-status="cancelled"] { background: #9ca3af; }
.lucid-swatch.is-late { background: transparent; border: 2px solid var(--lucid-danger); }

/* ==========================================================================
   Production flow — one garment's chain as connected boxes.

   Two screens share this block: the picker (which garment?) and the graph.
   The graph's columns are laid out by CSS; the wires between them are SVG
   drawn from measured card positions, because the server cannot know where a
   card lands once its name wraps to two lines.
   ========================================================================== */

/* ---- the picker ---------------------------------------------------------- */
.lucid-pick-grid {
  display: grid; gap: .7rem;
  grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
}
.lucid-pick {
  position: relative;
  display: block; padding: .8rem .9rem;
  border: 1px solid var(--color-base-200); border-radius: .6rem;
  text-decoration: none; color: inherit;
  transition: border-color .12s, transform .12s;
}
.dark .lucid-pick { border-color: var(--color-base-800); }
.lucid-pick:hover {
  border-color: var(--color-primary-500);
  transform: translateY(-1px);
}
/* A garment with no recipe has nothing to draw; say so before the click. */
.lucid-pick.is-flat { opacity: .6; }
.lucid-pick-name { font-size: .85rem; font-weight: 600; line-height: 1.2; }
.lucid-pick-qty {
  font-size: 1.6rem; font-weight: 300; line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--color-primary-500);
}
.lucid-pick-foot {
  display: flex; align-items: center; gap: .4rem;
  font-size: .68rem; opacity: .6;
}

/* ---- the header ---------------------------------------------------------- */
.lucid-flow-head-row { display: flex; align-items: flex-start; gap: 1rem; flex-wrap: wrap; }
.lucid-flow-title { font-size: 1.35rem; font-weight: 600; line-height: 1.15; }
.lucid-break {
  display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
  margin-top: .75rem; padding: .55rem .7rem; border-radius: .5rem;
  background: color-mix(in oklab, var(--lucid-danger) 9%, transparent);
}
.lucid-break.is-ok { background: color-mix(in oklab, var(--lucid-ok) 9%, transparent); }

/* ---- the graph ----------------------------------------------------------- */
/* `width: max-content` so the wires' coordinate space is the *content*, not
   the scroll viewport — an absolutely positioned SVG inside a scroller stays
   put while the boxes slide away underneath it. */
.lucid-graph { position: relative; width: max-content; min-width: 100%; padding: .25rem 0 .5rem; }
.lucid-wires { position: absolute; inset: 0; pointer-events: none; overflow: visible; }
.lucid-wire { fill: none; stroke-width: 1.5; opacity: .75; }
.lucid-wire[data-flow="late"]    { stroke: var(--lucid-danger); stroke-width: 2.2; }
.lucid-wire[data-flow="missing"] { stroke: var(--lucid-warn); stroke-dasharray: 5 4; }
.lucid-wire[data-flow="running"] { stroke: var(--lucid-info); }
.lucid-wire[data-flow="done"]    { stroke: var(--lucid-ok); }
/* The label sits on top of its own wire, so it gets a halo in the card colour
   rather than a box — a box that size is bigger than the number in it. */
.lucid-wire-label {
  font-size: .62rem; fill: currentColor; opacity: .65;
  font-variant-numeric: tabular-nums;
  paint-order: stroke fill;
  stroke: var(--color-base-50); stroke-width: 3px; stroke-linejoin: round;
}
.dark .lucid-wire-label { stroke: var(--color-base-900); }

/* Columns are recipe depth. `align-items: center` keeps the wires short and
   roughly horizontal, which is what makes the chain readable at a glance. */
.lucid-graph-cols { display: flex; align-items: center; gap: 4rem; }
.lucid-graph-col { display: flex; flex-direction: column; gap: .9rem; width: 15rem; flex: none; }
.lucid-graph-coltitle { text-align: center; }

/* ---- one box ------------------------------------------------------------- */
.lucid-node {
  position: relative; z-index: 1;
  display: flex; flex-direction: column; gap: .3rem;
  padding: .6rem .7rem;
  border: 1px solid var(--color-base-200); border-radius: .55rem;
  background: var(--color-base-50);
  border-inline-start-width: 3px;
}
.dark .lucid-node { border-color: var(--color-base-800); background: var(--color-base-900); }
.lucid-node[data-flow="late"]    { border-inline-start-color: var(--lucid-danger); }
.lucid-node[data-flow="missing"] { border-inline-start-color: var(--lucid-warn); }
.lucid-node[data-flow="running"] { border-inline-start-color: var(--lucid-info); }
.lucid-node[data-flow="done"]    { border-inline-start-color: var(--lucid-ok); }
/* Buying and making are different kinds of work; a dashed edge separates them
   without spending a second colour on it. */
.lucid-node[data-kind="make"] { border-inline-start-style: double; border-inline-start-width: 4px; }

.lucid-node-head {
  display: flex; align-items: center; gap: .35rem;
  font-size: .66rem; text-transform: uppercase; letter-spacing: .04em; opacity: .6;
}
.lucid-node-title {
  font-size: .92rem; font-weight: 600; line-height: 1.15;
  text-decoration: none; color: inherit;
}
.lucid-node-title:hover { text-decoration: underline; }
.lucid-node-share { font-size: .7rem; }
.lucid-node-share b { font-variant-numeric: tabular-nums; }

/* How much of this step reality already covers. A half-filled meter is
   half-solved, which three numbers side by side cannot say. */
.lucid-node-meter {
  height: .35rem; border-radius: 999px; overflow: hidden;
  background: color-mix(in oklab, var(--color-base-500) 16%, transparent);
}
.lucid-node-meter-fill { display: block; height: 100%; }
.lucid-node-meter-fill[data-flow="late"]    { background: var(--lucid-danger); }
.lucid-node-meter-fill[data-flow="missing"] { background: var(--lucid-warn); }
.lucid-node-meter-fill[data-flow="running"] { background: var(--lucid-info); }
.lucid-node-meter-fill[data-flow="done"]    { background: var(--lucid-ok); }

.lucid-node-facts {
  display: flex; gap: .5rem; flex-wrap: wrap;
  font-size: .66rem; opacity: .7; font-variant-numeric: tabular-nums;
}
.lucid-node-facts .lucid-danger { opacity: 1; font-weight: 600; }
.lucid-node-when { font-size: .66rem; opacity: .6; }

/* The strip is the same date window for every box on the page, so two blocks
   at the same x really are the same week. */
.lucid-node-track {
  position: relative; height: .9rem; margin-top: .1rem;
  border-top: 1px dashed color-mix(in oklab, var(--color-base-500) 20%, transparent);
}
/* A one-day order at nine-month scale is a quarter of a pixel; a floor of 8
   keeps it a block rather than a speck, and a speck reads as absent. */
.lucid-node-bar {
  position: absolute; top: .2rem; height: .6rem; min-width: 8px;
  border-radius: .15rem; border: 1px solid transparent;
}
.lucid-node-bar[data-flow="late"] {
  background: color-mix(in oklab, var(--lucid-danger) 22%, transparent);
  border-color: var(--lucid-danger);
}
.lucid-node-bar[data-flow="missing"] {
  background: color-mix(in oklab, var(--lucid-warn) 18%, transparent);
  border-color: var(--lucid-warn); border-style: dashed;
}
.lucid-node-bar[data-flow="running"] {
  background: color-mix(in oklab, var(--lucid-info) 18%, transparent);
  border-color: var(--lucid-info);
}
.lucid-node-bar[data-flow="done"] {
  background: color-mix(in oklab, var(--lucid-ok) 18%, transparent);
  border-color: var(--lucid-ok);
}
.lucid-node-none { font-size: .62rem; opacity: .4; line-height: .9rem; }

/* Naming the upstream cause is the whole point: a step blocked by its input
   is not independently fixable, and chasing it wastes a morning. */
.lucid-node-blocked {
  font-size: .64rem; padding: .18rem .35rem; border-radius: .25rem;
  background: color-mix(in oklab, var(--lucid-warn) 14%, transparent);
}

.lucid-dot { width: .6rem; height: .6rem; border-radius: 999px; display: inline-block; flex: none; }
.lucid-dot[data-flow="late"]    { background: var(--lucid-danger); }
.lucid-dot[data-flow="missing"] { background: var(--lucid-warn); }
.lucid-dot[data-flow="running"] { background: var(--lucid-info); }
.lucid-dot[data-flow="done"]    { background: var(--lucid-ok); }

/* ---- plan-versus-reality bar --------------------------------------------
   One bar per garment, segmented by where the cover comes from. Replaces six
   numeric columns people were asked to subtract in their heads. */
.lucid-cover { display: flex; height: 1.15rem; border-radius: .25rem; overflow: hidden;
               background: color-mix(in oklab, var(--color-base-500) 12%, transparent); }
.lucid-cover i { display: block; height: 100%; }
.lucid-cover i[data-part="sold"]      { background: color-mix(in oklab, var(--lucid-ok) 70%, transparent); }
.lucid-cover i[data-part="stock"]     { background: var(--lucid-ok); }
.lucid-cover i[data-part="progress"]  { background: var(--lucid-info); }
.lucid-cover i[data-part="uncovered"] { background: color-mix(in oklab, var(--lucid-danger) 55%, transparent); }
.lucid-cover-key { display: flex; gap: .9rem; flex-wrap: wrap; font-size: .7rem; opacity: .75; }
.lucid-cover-key i { width: .9rem; height: .55rem; border-radius: 2px; display: inline-block; margin-inline-end: .3rem; }

/* ---- the year as twelve blocks of work ----------------------------------
   The dashboard's one piece of shape. A count of things to do is flat; spread
   across months it shows *when* the year gets hard, which is the only version
   of that number you can act on. */
.lucid-months { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: .4rem; }
.lucid-month {
  display: flex; flex-direction: column; gap: .1rem; align-items: center;
  padding: .55rem .3rem; border-radius: .4rem; text-decoration: none;
  border: 1px solid var(--color-base-200);
  background: color-mix(in oklab, var(--color-base-500) 5%, transparent);
  transition: transform .08s ease;
}
.dark .lucid-month { border-color: var(--color-base-800); }
.lucid-month:hover { transform: translateY(-1px); }
.lucid-month[data-flow="late"] {
  border-color: var(--lucid-danger);
  background: color-mix(in oklab, var(--lucid-danger) 14%, transparent);
}
.lucid-month[data-flow="missing"] {
  border-color: color-mix(in oklab, var(--lucid-warn) 60%, transparent);
  background: color-mix(in oklab, var(--lucid-warn) 10%, transparent);
}
.lucid-month-name  { font-size: .65rem; text-transform: uppercase; letter-spacing: .04em; opacity: .6; }
.lucid-month-count { font-size: 1.15rem; font-weight: 600; line-height: 1.1; }
.lucid-month-late  { font-size: .6rem; color: var(--lucid-danger); font-weight: 600; }
.lucid-month-value { font-size: .6rem; opacity: .55; }

/* Twelve columns stop being legible well before they stop fitting. */
@media (max-width: 1100px) { .lucid-months { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
@media (max-width: 640px)  { .lucid-months { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* ------------------------------------------------------------ plans

   A plan's year is the most important thing about it, so it is typeset like a
   headline rather than hidden inside a dropdown label. */

.lucid-year { margin-bottom: 1.75rem; }
.lucid-year-head {
  display: flex; align-items: baseline; gap: .75rem;
  padding-bottom: .4rem; margin-bottom: .6rem;
  border-bottom: 1px solid var(--color-base-200);
}
.dark .lucid-year-head { border-bottom-color: var(--color-base-800); }
.lucid-year-number { font-size: 1.6rem; font-weight: 650; letter-spacing: -.02em; }

.lucid-plan-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: .75rem;
}
.lucid-plan-card {
  display: block; position: relative;
  padding: .85rem 1rem;
  border: 1px solid var(--color-base-200);
  border-radius: .55rem;
  text-decoration: none; color: inherit;
  transition: border-color .12s, background .12s;
}
.dark .lucid-plan-card { border-color: var(--color-base-800); }
.lucid-plan-card:hover {
  border-color: var(--color-primary-500);
  background: color-mix(in oklab, var(--color-primary-500) 6%, transparent);
}
.lucid-plan-card.is-objective { border-left: 3px solid var(--lucid-warn); }
.lucid-plan-name { font-weight: 600; display: flex; align-items: center; gap: .4rem; }
.lucid-plan-year {
  position: absolute; top: .7rem; right: 1rem;
  font-size: 1.5rem; font-weight: 650; opacity: .13;
  letter-spacing: -.02em; line-height: 1;
}
.lucid-plan-facts {
  display: flex; flex-wrap: wrap; gap: .6rem;
  font-size: .72rem; opacity: .8; margin-top: .35rem;
}
.lucid-plan-status { font-size: .68rem; opacity: .5; margin-top: .3rem; text-transform: uppercase; }

/* Which plan the year is actually run on.
 *
 * The shelf used to print the plan's lifecycle `status` here, so three plans on
 * a year all read ACTIVE and the one question a planner arrives with — "which
 * of these is the real one" — had no answer on the page. `standing` answers it
 * instead, and the selected card is marked strongly enough to find without
 * reading: one per year, by database constraint. */
.lucid-plan-open { display: block; text-decoration: none; color: inherit; }
.lucid-plan-standing {
  display: flex; align-items: center; gap: .4rem;
  font-size: .68rem; margin-top: .45rem; text-transform: uppercase;
  letter-spacing: .04em; opacity: .55;
}
.lucid-plan-standing[data-standing="running-the-year"] { opacity: 1; color: var(--lucid-ok); font-weight: 600; }
.lucid-plan-standing[data-standing="used-by-default"] { opacity: .85; color: var(--lucid-warn); }
.lucid-plan-card.is-selected {
  border-color: var(--lucid-ok);
  box-shadow: inset 3px 0 0 var(--lucid-ok);
}
.lucid-plan-pick { margin-left: auto; }
.lucid-plan-pick .lucid-btn-ghost { font-size: .68rem; padding: .1rem .45rem; }
.lucid-plan-card:not(:hover) .lucid-plan-pick { opacity: 0; }
.lucid-plan-card:hover .lucid-plan-pick { opacity: 1; }

.lucid-year-runs { margin-left: auto; font-size: .74rem; opacity: .75; }
.lucid-year-runs.is-undecided { color: var(--lucid-warn); opacity: 1; }

/* The cockpit header: year, name, state, and every other plan one click away. */
.lucid-plan-head {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  padding-bottom: .9rem; margin-bottom: 1rem;
  border-bottom: 1px solid var(--color-base-200);
}
.dark .lucid-plan-head { border-bottom-color: var(--color-base-800); }
.lucid-plan-back {
  display: inline-block; margin-inline-start: -.5rem;
  font-size: 1.2rem; text-decoration: none; opacity: .5;
  padding: .2rem .5rem; border-radius: .35rem;
}
.lucid-plan-back:hover { opacity: 1; background: color-mix(in oklab, var(--color-base-500) 10%, transparent); }
.lucid-plan-title { display: flex; align-items: center; gap: .9rem; }
.lucid-plan-title-year {
  font-size: 2.4rem; font-weight: 700; line-height: 1;
  letter-spacing: -.03em;
  color: var(--color-primary-500);
}
.lucid-plan-title-name { font-size: 1.05rem; font-weight: 600; display: flex; align-items: center; gap: .45rem; }
.lucid-plan-title-sub { font-size: .74rem; opacity: .7; }

.lucid-plan-switch { display: flex; gap: 1rem; margin-inline-start: auto; flex-wrap: wrap; }
.lucid-plan-switch-year { display: flex; align-items: center; gap: .3rem; }
.lucid-chip {
  font-size: .72rem; padding: .2rem .55rem; border-radius: 999px;
  border: 1px solid var(--color-base-300); text-decoration: none; color: inherit;
}
.dark .lucid-chip { border-color: var(--color-base-700); }
.lucid-chip:hover { border-color: var(--color-primary-500); }
.lucid-chip.is-active {
  background: var(--color-primary-500);
  border-color: var(--color-primary-500);
  color: white;
}
.lucid-check { display: flex; align-items: center; gap: .4rem; font-size: .8rem; white-space: nowrap; }

/* ------------------------------------------------------------------ plan detail
   The panel behind a cockpit row. It sits inside the table, so it has to look
   like a drawer rather than another row of data — hence the inset background
   and the left rule tying it to the row above. */
.lucid-cell-expand { white-space: nowrap; }
.lucid-expand {
  border: 0; background: none; cursor: pointer; font-size: 1rem; line-height: 1;
  padding: .1rem .35rem; margin-inline-end: .25rem; border-radius: .25rem;
  color: var(--color-base-500);
}
.lucid-expand:hover { background: color-mix(in oklab, var(--color-primary-500) 14%, transparent); }
.lucid-expand[aria-expanded="true"] { color: var(--color-primary-500); }

.lucid-detail-row > td { padding: 0 !important; background: color-mix(in oklab, var(--color-base-500) 6%, transparent); }
.lucid-detail-slot { padding: 1rem 1rem 1rem 2.25rem; border-inline-start: 3px solid var(--color-primary-500); }
.lucid-detail { display: grid; gap: 1.25rem; }
.lucid-detail-block { display: grid; gap: .4rem; }
.lucid-detail-head { display: flex; align-items: baseline; gap: 1rem; flex-wrap: wrap; }
.lucid-detail-legend { display: flex; gap: .75rem; font-size: .7rem; opacity: .75; margin-inline-start: auto; }
.lucid-swatch { display: inline-block; width: .6rem; height: .6rem; border-radius: .15rem; margin-inline-end: .3rem; }

/* One column per month. Bars overlap rather than stack: plan and actual are two
   answers to the same question, and stacking them would read as a sum. */
.lucid-mstrip { display: flex; gap: .35rem; align-items: flex-end; height: 7rem; }
.lucid-mcol { flex: 1; display: flex; flex-direction: column; height: 100%; }
.lucid-mcol.is-closed { opacity: .38; }
.lucid-mcol-stack { position: relative; flex: 1; display: flex; align-items: flex-end; gap: 2px; }
.lucid-mcol-bar { flex: 1; min-height: 2px; border-radius: .15rem .15rem 0 0; }
.lucid-mcol-tick { position: absolute; left: 0; right: 0; height: 2px; }
.lucid-mcol-label { font-size: .62rem; text-align: center; opacity: .65; padding-top: .25rem; }

.lucid-swatch[data-kind="plan"],     .lucid-mcol-bar[data-kind="plan"]     { background: color-mix(in oklab, var(--color-primary-500) 55%, transparent); }
.lucid-swatch[data-kind="preorder"], .lucid-mcol-bar[data-kind="preorder"] { background: color-mix(in oklab, var(--lucid-warn) 65%, transparent); }
.lucid-swatch[data-kind="actual"],   .lucid-mcol-bar[data-kind="actual"]   { background: var(--color-base-600); }
.lucid-swatch[data-kind="proposed"], .lucid-mcol-tick[data-kind="proposed"]{ background: var(--lucid-danger); }

.lucid-detail-drift { display: flex; gap: 2rem; align-items: center; flex-wrap: wrap; }
.lucid-detail-drift.is-off .lucid-detail-ratio { color: var(--lucid-danger); }
.lucid-detail-ratio { font-size: 1.35rem; font-weight: 600; }
.lucid-metric-sm { font-size: 1.35rem; font-weight: 600; }
.lucid-detail-windows { list-style: none; padding: 0; margin: 0; display: grid; gap: .3rem; }

/* A scenario has to be visibly not-the-live-plan, or somebody edits the wrong
   one for twenty minutes before noticing. */
.lucid-scenario-note { border-inline-start: 3px solid var(--lucid-warn); }
.lucid-plan-actions { display: flex; gap: .5rem; align-items: center; }
.lucid-chip.is-selected { border-color: var(--lucid-ok); font-weight: 600; }


/* A caveat that changes what the numbers beside it mean.
 *
 * Not a warning — nothing is broken — but the forecast-accuracy tiles read as
 * findings ("0% off plan") when they are sometimes identities, and a reader who
 * misses that draws exactly the wrong conclusion. Placed above the numbers
 * rather than under them for the same reason. */
.lucid-note {
  border-left: 3px solid var(--lucid-warn);
  background: color-mix(in oklab, var(--lucid-warn) 7%, transparent);
  padding: .6rem .8rem; border-radius: .35rem;
  font-size: .8rem; line-height: 1.45;
}
.lucid-note > div + div { margin-top: .45rem; }


/* Mid-year, the year total is not the thing you choose — it is settled plus
 * what you choose. Showing the sum as a consequence of the editable half is
 * the whole point: an annual box in August reads as control over the year and
 * gives you control over about a third of it. */
.lucid-split { display: flex; align-items: center; justify-content: flex-end; gap: .3rem; }
.lucid-split-sold {
  display: inline-flex; flex-direction: column; align-items: flex-end;
  font-variant-numeric: tabular-nums; opacity: .55; line-height: 1;
}
.lucid-split-sold i { font-style: normal; font-size: .58rem; text-transform: uppercase; letter-spacing: .04em; }
.lucid-split-plus { opacity: .4; }
.lucid-split-year { font-size: .66rem; opacity: .6; text-align: right; margin-top: .15rem; }
.lucid-split-year b { font-variant-numeric: tabular-nums; opacity: .95; }

/* The chart mixes a planned side with a committed one. Amber rather than grey:
 * it is not a footnote, it is the reason the balance looks the way it does. */
.lucid-basis-note { color: var(--lucid-warn); opacity: .85; }
.lucid-basis-note a { text-decoration: underline; }

/* Offer windows, on the collapsed row. "1sp · 2psp" is deliberately terse: it
 * has to fit beside the channel and be scannable down sixty rows. Red when
 * there are none, because that line cannot resolve at all. */
.lucid-windows {
  display: inline-block; margin-left: .4rem; padding: .05rem .3rem;
  font-size: .6rem; font-variant-numeric: tabular-nums; letter-spacing: .02em;
  border-radius: .25rem; opacity: .75; vertical-align: 1px;
  background: color-mix(in oklab, var(--color-base-500) 14%, transparent);
}
.dark .lucid-windows { background: color-mix(in oklab, var(--color-base-100) 10%, transparent); }
/* No window is not "planned at zero" — the line cannot resolve at all (C9), so
 * it reads as the failure it is rather than as a quiet count of nothing. */
.lucid-windows.is-missing {
  color: var(--lucid-danger); opacity: 1; font-weight: 600;
  background: color-mix(in oklab, var(--lucid-danger) 16%, transparent);
}

/* The two comparison curves: this garment past, and the one it is modelled on.
 * Dots rather than a drawn line — twelve of them read as a curve, cost no
 * chart library, and never disagree with the bar they sit above. */
.lucid-mcol-dot {
  position: absolute; left: 50%; width: .34rem; height: .34rem;
  margin-left: -.17rem; margin-bottom: -.17rem; border-radius: 50%;
  pointer-events: auto;
}
.lucid-mcol-dot[data-kind=history] { background: var(--color-base-400); }
.lucid-mcol-dot[data-kind=reference] {
  background: transparent; border: 1.5px solid var(--lucid-warn);
}
.lucid-swatch[data-kind=history] { background: var(--color-base-400); }
.lucid-swatch[data-kind=reference] {
  background: transparent; border: 1.5px solid var(--lucid-warn);
}

/* A preorder month is a different kind of month, not a quieter one: the orders
 * land here and the goods leave later (C1). Hatched so the strip shows when the
 * campaign was open without needing the list underneath. */
.lucid-mcol.is-presale .lucid-mcol-stack {
  background-image: repeating-linear-gradient(
    45deg, transparent, transparent 3px,
    color-mix(in oklab, var(--lucid-warn) 14%, transparent) 3px,
    color-mix(in oklab, var(--lucid-warn) 14%, transparent) 6px);
}

.lucid-shape-bar { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin-top: .6rem; }
.lucid-shape-pick { display: flex; align-items: center; gap: .35rem; margin-left: auto; }
.lucid-shape-pick .lucid-select { font-size: .72rem; padding: .1rem .3rem; }

/* ---------------------------------------------------------------- the product row
   The cockpit is one row per garment; its channels live in a panel underneath.
   That panel is rendered with the page and merely hidden, because its inputs
   are what the form submits — a row nobody opened still has to save. */

.lucid-channels-row > td,
tr.js-channels-row > td {
  padding: 0 !important;
  background: color-mix(in oklab, var(--color-base-500) 6%, transparent);
}
.lucid-channel-table { width: 100%; margin: 0 1rem 1rem 2.25rem; width: calc(100% - 3.25rem); }
.lucid-table-tight th, .lucid-table-tight td { padding-block: .3rem; font-size: .8rem; }
.lucid-channel-table thead th { font-size: .68rem; text-transform: uppercase; opacity: .6; }

/* Stacked bands: one per channel, offset by the running total beneath it, so a
   column's height is the production run and each band is where it goes. Unlike
   the single-line strip above — where plan and actual overlap because they are
   two answers to one question — these genuinely sum. */
.lucid-mcol-band {
  position: absolute;
  left: 0;
  right: 0;
  min-height: 2px;
  border-radius: .15rem .15rem 0 0;
}
.lucid-mcol-band[data-band="0"], .lucid-swatch[data-band="0"] { background: color-mix(in oklab, var(--color-primary-500) 70%, transparent); }
.lucid-mcol-band[data-band="1"], .lucid-swatch[data-band="1"] { background: color-mix(in oklab, var(--lucid-warn) 70%, transparent); }
.lucid-mcol-band[data-band="2"], .lucid-swatch[data-band="2"] { background: color-mix(in oklab, var(--lucid-ok) 60%, transparent); }
.lucid-mcol-band[data-band="3"], .lucid-swatch[data-band="3"] { background: color-mix(in oklab, var(--color-base-500) 55%, transparent); }
/* A fifth channel is not a design, it is a warning — but it must still draw. */
.lucid-mcol-band[data-band="4"], .lucid-swatch[data-band="4"] { background: color-mix(in oklab, var(--lucid-danger) 55%, transparent); }
.lucid-mcol-tick[data-kind="actual"] { background: var(--color-base-700); }

/* The product row reads as the heading of its own block. */
tr.js-product-row > td { font-weight: 500; }
tr.js-product-row .lucid-basis { font-weight: 400; }

/* ------------------------------------------------------------- data quality
   Severity is a colour and a rank at once: blocked is the only one that means
   "this row is not in the database", so it is the only one that reads as red.
   Assumed is amber rather than grey on purpose — a derived value looks exactly
   like a stated one everywhere else in the app. */

.lucid-steps { display: flex; gap: .5rem; flex-wrap: wrap; }
.lucid-step {
  flex: 1 1 7rem; min-width: 7rem; padding: .6rem .7rem; border-radius: .4rem;
  text-decoration: none; color: inherit;
  background: color-mix(in oklab, var(--color-base-500) 8%, transparent);
  border-inline-start: 3px solid var(--color-base-400);
}
.lucid-step:hover { background: color-mix(in oklab, var(--color-primary-500) 12%, transparent); }
.lucid-step-count { font-size: 1.35rem; font-weight: 600; line-height: 1.1; }
.lucid-step-label { font-size: .68rem; opacity: .7; text-transform: uppercase; letter-spacing: .02em; }
.lucid-step[data-worst="blocked"]  { border-inline-start-color: var(--lucid-danger); }
.lucid-step[data-worst="degraded"] { border-inline-start-color: var(--lucid-warn); }
.lucid-step[data-worst="assumed"]  { border-inline-start-color: #d97706; }
.lucid-step[data-worst="ignored"]  { border-inline-start-color: var(--color-base-400); }

.lucid-issue { border-inline-start: 3px solid var(--color-base-400); }
.lucid-issue[data-severity="blocked"]  { border-inline-start-color: var(--lucid-danger); }
.lucid-issue[data-severity="degraded"] { border-inline-start-color: var(--lucid-warn); }
.lucid-issue[data-severity="assumed"]  { border-inline-start-color: #d97706; }
.lucid-issue-head { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap; }
.lucid-issue-text { flex: 1; }
.lucid-issue-count {
  font-variant-numeric: tabular-nums; font-weight: 600;
  padding: .05rem .45rem; border-radius: .3rem;
  background: color-mix(in oklab, var(--color-base-500) 14%, transparent);
}
.lucid-issue-step { font-size: .66rem; text-transform: uppercase; opacity: .6; letter-spacing: .03em; }
.lucid-issue-why { font-size: .8rem; opacity: .8; margin-top: .35rem; }
.lucid-issue-fix { font-size: .8rem; margin-top: .25rem; color: var(--color-primary-500); }
.lucid-issue-rows summary { font-size: .72rem; opacity: .65; cursor: pointer; margin-top: .4rem; }
.lucid-pill[data-severity="blocked"]  { background: color-mix(in oklab, var(--lucid-danger) 22%, transparent); }
.lucid-pill[data-severity="degraded"] { background: color-mix(in oklab, var(--lucid-warn) 25%, transparent); }
.lucid-pill[data-severity="assumed"]  { background: color-mix(in oklab, #d97706 25%, transparent); }
.lucid-pill[data-severity="ignored"]  { background: color-mix(in oklab, var(--color-base-500) 18%, transparent); }
.lucid-btn-ghost.is-active { background: color-mix(in oklab, var(--color-primary-500) 18%, transparent); }

/* Setup instructions: commands are meant to be copied, so they get room and a
   background rather than being squeezed into the body text. */
.lucid-code {
  background: color-mix(in oklab, var(--color-base-500) 12%, transparent);
  border-radius: .4rem; padding: .7rem .9rem; font-size: .78rem;
  overflow-x: auto; white-space: pre; line-height: 1.5;
}
