/* THE DIARY REDESIGN, shared components.
 *
 * Loaded AFTER /appts-shell.css and adds nothing to the token layer. Every
 * colour, radius, easing and font is a token from the client app's own sheet,
 * so these components cannot drift from it.
 *
 * COLOUR MEANS SOMETHING HERE, and it has to, because this page is about
 * substances and a decorative palette would read as a judgement:
 *   magenta  the primary action, and an entry that records USE
 *   teal     a day got through, and anything protective
 *   cyan     information, and the platform's own signals (mood, sleep, craving)
 *   gold     a soft warning, and the amber safety tier
 *   red      the red safety tier ONLY, which is a route to a person
 * Nothing is coloured to mean "bad". A drinking day is magenta because it is
 * an entry, not because it is a failure.
 */

/* ---- the day, wherever it appears --------------------------------------- */
.dx-dot{width:11px;height:11px;border-radius:50%;flex-shrink:0;display:inline-block}
.dx-dot.use{background:var(--secondary)}
.dx-dot.avoided{background:var(--teal)}
.dx-dot.none{background:transparent;box-shadow:inset 0 0 0 2px var(--teal-soft)}
.dx-dot.unknown{background:transparent;box-shadow:inset 0 0 0 1.5px var(--hair-2)}

.dx-legend{display:flex;gap:16px;flex-wrap:wrap;font-size:12px;color:var(--ink-3)}
.dx-legend span{display:inline-flex;align-items:center;gap:7px}

/* ---- THE TIMELINE ------------------------------------------------------
   Andy's "My Journey": a run of days that carries the CHAIN under each one,
   which a calendar grid cannot do. Horizontal scroll on purpose, because the
   thing you want is the last fortnight in order, not a month in a box. */
.dx-tl{display:flex;gap:0;overflow-x:auto;padding:4px 0 10px;scrollbar-width:none;
  -webkit-overflow-scrolling:touch}
.dx-tl::-webkit-scrollbar{display:none}
.dx-tl-day{flex:0 0 108px;display:flex;flex-direction:column;align-items:center;gap:9px;
  padding:16px 8px 14px;border-right:1px solid var(--hair);position:relative;
  transition:background .2s var(--ease)}
.dx-tl-day:last-child{border-right:0}
.dx-tl-day:hover{background:var(--raise-2)}
.dx-tl-day[aria-pressed="true"]{background:rgba(181,37,85,.12)}
.dx-tl-dow{font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink-3)}
.dx-tl-day.today .dx-tl-dow{color:var(--secondary-soft)}
html[data-theme="light"] .dx-tl-day.today .dx-tl-dow{color:var(--secondary)}
.dx-tl-face{width:40px;height:40px;border-radius:50%;display:grid;place-items:center;
  background:var(--raise-2);box-shadow:0 0 0 1px var(--hair)}
.dx-tl-face.use{background:rgba(181,37,85,.2);box-shadow:0 0 0 1px rgba(181,37,85,.4)}
.dx-tl-face.avoided{background:rgba(0,164,153,.2);box-shadow:0 0 0 1px rgba(0,164,153,.45)}
.dx-tl-face.none{background:rgba(0,164,153,.1)}
.dx-tl-lab{font-size:12px;font-weight:650;text-align:center;line-height:1.25}
.dx-tl-sub{font-size:11px;color:var(--ink-3);text-align:center;line-height:1.3;min-height:2.4em}
/* the thread that hangs the trigger under the day, which is the whole point */
.dx-tl-thread{width:1px;flex:1;min-height:16px;background:var(--hair)}
.dx-tl-trig{font-size:10.5px;color:var(--gold-soft,#E7C476);text-align:center;line-height:1.3;
  padding:0 2px}
html[data-theme="light"] .dx-tl-trig{color:var(--amber)}

/* ---- THE BEHAVIOUR CHAIN ------------------------------------------------
   One entry read as the sequence it was. A missing link is shown as missing,
   because the gaps are the useful part in a conversation with a worker. */
.dx-chain{display:flex;flex-direction:column;gap:0}
.dx-link{display:grid;grid-template-columns:34px 1fr;gap:16px;position:relative;padding-bottom:18px}
.dx-link:last-child{padding-bottom:0}
.dx-link-rail{display:flex;flex-direction:column;align-items:center;gap:0}
.dx-link-n{width:34px;height:34px;border-radius:50%;flex-shrink:0;display:grid;place-items:center;
  background:var(--raise-2);box-shadow:0 0 0 1px var(--hair);color:var(--ink-3)}
.dx-link.on .dx-link-n{background:var(--secondary);color:#fff;box-shadow:none}
.dx-link.ok .dx-link-n{background:var(--teal);color:#fff;box-shadow:none}
.dx-link.gap .dx-link-n{background:transparent;box-shadow:inset 0 0 0 1.5px var(--hair-2)}
.dx-link-line{width:1px;flex:1;background:var(--hair);margin:4px 0}
.dx-link:last-child .dx-link-line{display:none}
.dx-link-b{padding-top:5px;min-width:0}
.dx-link-k{display:block;font-size:11px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:4px}
.dx-link-v{display:block;font-size:15.5px;font-weight:600;line-height:1.35}
.dx-link.gap .dx-link-v{font-weight:400;color:var(--ink-3);font-style:italic}
.dx-link-s{display:block;font-size:11.5px;color:var(--ink-3);margin-top:3px}

/* ---- WHAT WORKS FOR YOU ------------------------------------------------- */
.dx-works{display:flex;flex-direction:column;gap:10px}
.dx-work{display:flex;align-items:center;gap:15px;padding:16px 18px;border-radius:var(--r-md);
  background:var(--raise);border:1px solid var(--hair)}
.dx-work-rank{width:30px;height:30px;border-radius:50%;flex-shrink:0;display:grid;place-items:center;
  font-family:var(--display);font-size:13px;font-weight:700;background:rgba(0,164,153,.2);
  color:var(--teal-soft)}
html[data-theme="light"] .dx-work-rank{background:#DFF3F0;color:#0B7A6F}
.dx-work-tx{flex:1;min-width:0}
.dx-work-tx b{display:block;font-size:15px;font-weight:650;line-height:1.3}
.dx-work-tx span{display:block;font-size:12.5px;color:var(--ink-3);margin-top:3px}
.dx-work-bar{flex:none;width:96px}
.dx-work-bar i{display:block;height:6px;border-radius:3px;background:var(--teal);
  transition:width 1s var(--spring)}
.dx-work-bar span{display:block;font-size:11px;color:var(--ink-3);margin-top:6px;text-align:right}
@media(max-width:560px){.dx-work-bar{display:none}}

/* ---- risk by day, a bar per weekday ------------------------------------- */
.dx-risk{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:8px;align-items:end;
  height:150px}
.dx-risk-col{display:flex;flex-direction:column;justify-content:flex-end;align-items:center;gap:8px;
  height:100%}
.dx-risk-bar{width:100%;border-radius:8px 8px 3px 3px;background:var(--raise-2);
  min-height:4px;transition:height .9s var(--spring)}
.dx-risk-col.peak .dx-risk-bar{background:linear-gradient(180deg,var(--secondary),rgba(181,37,85,.35))}
.dx-risk-col:not(.peak) .dx-risk-bar{background:linear-gradient(180deg,var(--cyan-soft),rgba(0,119,200,.25))}
.dx-risk-lab{font-size:11px;font-weight:650;color:var(--ink-3)}
.dx-risk-col.peak .dx-risk-lab{color:var(--secondary-soft)}
html[data-theme="light"] .dx-risk-col.peak .dx-risk-lab{color:var(--secondary)}

/* ---- pattern rows, each carrying its own evidence ----------------------- */
.dx-pats{display:flex;flex-direction:column;gap:9px}
.dx-pat{display:flex;gap:14px;align-items:flex-start;padding:15px 17px;border-radius:var(--r-md);
  background:var(--raise);border:1px solid var(--hair)}
.dx-pat-ic{width:30px;height:30px;border-radius:10px;flex-shrink:0;display:grid;place-items:center;
  background:rgba(0,119,200,.2);color:var(--cyan-soft)}
html[data-theme="light"] .dx-pat-ic{background:#E6F2FA;color:var(--cyan)}
/* .dx-pat-tx, NOT a bare `.dx-pat span`. Written that way the rule is (0,1,1)
   and BEATS `.dx-pat-ic` at (0,1,0), so the icon disc laid out as a block and
   its glyph sat high and left inside the rounded square. Sixth time a generic
   descendant selector has eaten a component's own rule on this project, and
   the second time it has been an icon sitting wrong. */
.dx-pat-tx{flex:1;min-width:0}
.dx-pat-tx b{display:block;font-size:15px;font-weight:650;line-height:1.35}
.dx-pat-tx > span{display:block;font-size:12.5px;color:var(--ink-3);margin-top:4px}

/* ---- the safety layer, which never shouts ------------------------------- */
.dx-safe{padding:18px 20px;border-radius:var(--r-md);border:1px solid;margin-bottom:12px}
.dx-safe.amber{background:rgba(185,138,47,.14);border-color:rgba(185,138,47,.4)}
html[data-theme="light"] .dx-safe.amber{background:#FBEFD5;border-color:#E8D3A0}
.dx-safe.red{background:rgba(180,35,24,.14);border-color:rgba(180,35,24,.4)}
html[data-theme="light"] .dx-safe.red{background:#FDECEA;border-color:#F3C6C1}
.dx-safe b{display:block;font-size:15.5px;font-weight:650;margin-bottom:6px}
.dx-safe.amber b{color:#E7C476}
html[data-theme="light"] .dx-safe.amber b{color:var(--amber)}
.dx-safe.red b{color:#FF9C93}
html[data-theme="light"] .dx-safe.red b{color:#8E1A11}
.dx-safe p{font-size:14px;line-height:1.55;color:var(--ink-2);margin-bottom:14px}
.dx-safe .acts{display:flex;gap:8px;flex-wrap:wrap}
.dx-unsigned{display:inline-flex;align-items:center;gap:6px;margin-top:12px;padding:4px 10px;
  border-radius:999px;background:var(--raise-2);border:1px dashed var(--hair-2);
  font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-3)}

/* ---- the visibility model ----------------------------------------------- */
.dx-vis{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:12px}
.dx-vcard{padding:20px;border-radius:var(--r-md);background:var(--raise);border:1px solid var(--hair)}
.dx-vcard .who{display:inline-flex;align-items:center;gap:7px;padding:4px 11px;border-radius:999px;
  font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;margin-bottom:12px}
.dx-vcard.private .who{background:var(--raise-2);color:var(--ink-2)}
.dx-vcard.shared .who{background:rgba(0,119,200,.2);color:var(--cyan-soft)}
html[data-theme="light"] .dx-vcard.shared .who{background:#E6F2FA;color:var(--cyan)}
.dx-vcard.personal .who{background:rgba(0,164,153,.2);color:var(--teal-soft)}
html[data-theme="light"] .dx-vcard.personal .who{background:#DFF3F0;color:#0B7A6F}
.dx-vcard.safety .who{background:rgba(180,35,24,.18);color:#FF9C93}
html[data-theme="light"] .dx-vcard.safety .who{background:#FDECEA;color:#8E1A11}
.dx-vcard b{display:block;font-size:15.5px;font-weight:650;margin-bottom:7px}
.dx-vcard p{font-size:13.5px;line-height:1.55;color:var(--ink-2)}

/* ---- goals measured automatically --------------------------------------- */
.dx-goals{display:flex;flex-direction:column;gap:10px}
.dx-goal{display:flex;align-items:center;gap:15px;padding:16px 18px;border-radius:var(--r-md);
  background:var(--raise);border:1px solid var(--hair)}
.dx-goal-s{width:30px;height:30px;border-radius:50%;flex-shrink:0;display:grid;place-items:center;
  background:var(--raise-2);color:var(--ink-3)}
.dx-goal.met .dx-goal-s{background:var(--teal);color:#fff}
.dx-goal-tx{flex:1;min-width:0}
.dx-goal-tx b{display:block;font-size:15px;font-weight:600;line-height:1.35}
.dx-goal-tx span{display:block;font-size:12.5px;color:var(--ink-3);margin-top:4px}
.dx-goal-from{flex:none;font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--ink-3);padding:4px 10px;border-radius:999px;background:var(--raise-2)}
@media(max-width:600px){.dx-goal-from{display:none}}

/* ---- the log chooser and the before-I-use door -------------------------- */
.dx-doors{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}
.dx-door{display:flex;flex-direction:column;align-items:flex-start;gap:0;padding:22px;
  border-radius:var(--r-lg);border:1px solid var(--hair);background:var(--raise);width:100%;
  text-align:left;transition:transform .22s var(--spring),border-color .22s var(--ease)}
.dx-door:hover{transform:translateY(-2px);border-color:var(--hair-2)}
.dx-door .ic{width:44px;height:44px;border-radius:14px;display:grid;place-items:center;color:#fff;
  margin-bottom:16px}
.dx-door.now .ic{background:linear-gradient(150deg,var(--secondary),#7B2E63)}
.dx-door.used .ic{background:linear-gradient(150deg,var(--cyan),#12507F)}
.dx-door.got .ic{background:linear-gradient(150deg,var(--teal),#0A6E68)}
.dx-door b{display:block;font-family:var(--display);font-size:17px;font-weight:650;
  letter-spacing:-.02em;margin-bottom:6px}
.dx-door span{display:block;font-size:13.5px;color:var(--ink-2);line-height:1.5}

/* ---- pick lists inside the flows ---------------------------------------- */
.dx-pick{display:flex;flex-wrap:wrap;gap:8px}
.dx-pick button{padding:11px 16px;border-radius:999px;background:var(--raise-2);
  border:1px solid var(--hair);font:inherit;font-size:14px;font-weight:600;color:var(--ink-2);
  transition:all .2s var(--bounce)}
.dx-pick button:hover{background:var(--hair);color:var(--ink)}
.dx-pick button[aria-pressed="true"]{background:rgba(0,164,153,.2);border-color:var(--teal);
  color:var(--teal-soft)}
html[data-theme="light"] .dx-pick button[aria-pressed="true"]{background:#DFF3F0;color:#0B7A6F}
.dx-pick.mag button[aria-pressed="true"]{background:rgba(181,37,85,.2);border-color:var(--secondary);
  color:var(--secondary-soft)}
html[data-theme="light"] .dx-pick.mag button[aria-pressed="true"]{background:#F8E4EC;color:var(--secondary)}

/* ---- THE URGE SCALE ------------------------------------------------------
   Eleven identical flat boxes told you nothing: a 9 looked exactly like a 2,
   and the numbers sat left because the shell sets `text-align:left` on every
   button. This is a meter instead. The bars RISE across the scale so the shape
   carries the meaning before the number does, everything up to the chosen
   value fills, and the colour steps calm to intense at the same thresholds the
   read-out uses. Nothing is coloured to mean "bad": a 9 is not a failure, it
   is a 9. */
.dx-urge{display:flex;flex-direction:column;gap:12px}
.dx-urge-bars{display:flex;align-items:flex-end;gap:5px;height:76px}
.dx-urge-bars button{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:flex-end;
  align-items:center;gap:0;padding:0;background:none;border:0;cursor:pointer;height:100%}
.dx-urge-bars .b{display:block;width:100%;border-radius:7px 7px 3px 3px;background:var(--raise-2);
  box-shadow:inset 0 0 0 1px var(--hair);
  transition:background .22s var(--ease),box-shadow .22s var(--ease),transform .18s var(--bounce)}
.dx-urge-bars button:hover .b{background:var(--hair);transform:translateY(-2px)}
.dx-urge-bars button.on .b{box-shadow:none}
.dx-urge-bars button.on.lo .b{background:var(--cyan)}
.dx-urge-bars button.on.mid .b{background:var(--gold,#B98A2F)}
.dx-urge-bars button.on.hi .b{background:var(--secondary)}
/* the chosen bar itself, so the exact value is readable and not just the run */
.dx-urge-bars button.pick .b{box-shadow:0 0 0 2px var(--ink),0 0 0 4px var(--canvas)}
.dx-urge-nums{display:flex;gap:5px}
.dx-urge-nums span{flex:1;min-width:0;text-align:center;font-size:11px;font-weight:650;
  color:var(--ink-3);font-variant-numeric:tabular-nums}
.dx-urge-nums span.on{color:var(--ink)}
.dx-urge-read{display:flex;align-items:baseline;gap:12px;min-height:2.2em}
.dx-urge-read b{font-family:var(--display);font-size:32px;font-weight:700;letter-spacing:-.04em;
  line-height:1;font-variant-numeric:tabular-nums}
.dx-urge-read span{font-size:14.5px;color:var(--ink-2);line-height:1.4}
.dx-urge-read.empty b{color:var(--ink-3)}

/* ---- THE USE MAP -------------------------------------------------------
   NOT a heat grid. A grid of coloured squares is a spreadsheet with the
   numbers taken out: it is read left to right like a table, and the thing you
   actually want to see, that everything happens on the same two days, has to
   be counted rather than seen.

   So it is radial. Twelve weeks as rings, oldest at the centre and this week
   at the edge, and the seven days as spokes. A pattern tied to a DAY becomes a
   line running outward, which the eye finds instantly and without counting.
   Getting better over time becomes teal spreading towards the rim. It is
   opened from a card rather than sitting on the page, because it deserves the
   room and nobody needs it while they are logging.
   ------------------------------------------------------------------------ */

/* the card that opens it */
.dx-mapcard{display:flex;align-items:center;gap:26px;width:100%;text-align:left;padding:26px 30px;
  border-radius:var(--r-xl);border:1px solid var(--hair);background:var(--raise);flex-wrap:wrap;
  transition:transform .24s var(--spring),border-color .24s var(--ease),box-shadow .24s var(--ease)}
.dx-mapcard:hover{transform:translateY(-2px);border-color:var(--hair-2);box-shadow:var(--shadow)}
.dx-mapcard-art{width:112px;height:112px;flex-shrink:0;display:grid;place-items:center}
.dx-mapcard-art svg{width:100%;height:100%;display:block}
.dx-mapcard-tx{flex:1;min-width:220px}
.dx-mapcard-tx b{display:block;font-family:var(--display);font-size:21px;font-weight:650;
  letter-spacing:-.025em;margin-bottom:7px}
.dx-mapcard-tx p{font-size:14.5px;color:var(--ink-2);line-height:1.55;max-width:56ch}
.dx-mapcard-stats{display:flex;gap:26px;flex-wrap:wrap;margin-top:16px}
.dx-mapcard-stats span{display:block}
.dx-mapcard-stats b{display:block;font-family:var(--display);font-size:23px;font-weight:700;
  letter-spacing:-.03em;line-height:1;margin-bottom:5px}
.dx-mapcard-stats i{display:block;font-style:normal;font-size:12px;color:var(--ink-3)}
.dx-mapcard-go{flex:none;display:inline-flex;align-items:center;gap:8px;font-size:14.5px;
  font-weight:650;color:var(--secondary-soft);transition:gap .2s var(--spring)}
html[data-theme="light"] .dx-mapcard-go{color:var(--secondary)}
.dx-mapcard:hover .dx-mapcard-go{gap:12px}

/* the map itself */
.dx-sheet-map{width:min(1060px,100%)}
.dx-orbit{display:grid;grid-template-columns:minmax(0,1fr) 286px;gap:22px;align-items:start}
@media(max-width:900px){.dx-orbit{grid-template-columns:minmax(0,1fr)}}
/* FILL THE BOX, BOUNDED BY HEIGHT.
   Two failures to avoid, and they pull against each other. A fixed 560px map
   pushed the lower spokes and the last line of the key below the fold on a
   laptop; a 430px one left a third of the panel empty. So: take the whole
   column, and let the VIEWPORT HEIGHT be the only thing that shrinks it, since
   the sheet is capped at 90vh and the head, foot and padding take about 200px
   of that. 68vh is what is left. */
.dx-orbit-stage{position:relative;width:100%;aspect-ratio:1/1;
  max-width:min(100%,68vh);margin:0 auto}
.dx-orbit-stage svg{width:100%;height:100%;display:block;overflow:visible}
.dx-ring{fill:none;stroke:var(--hair);stroke-width:1}
.dx-ring.edge{stroke:var(--hair-2)}
.dx-spoke{stroke:var(--hair);stroke-width:1}
.dx-spoke-hit{fill:transparent;cursor:pointer}
.dx-spoke-lab{font-size:12px;font-weight:700;fill:var(--ink-3);text-anchor:middle;
  dominant-baseline:middle;letter-spacing:.05em}
.dx-spoke-lab.hot{fill:var(--secondary-soft)}
html[data-theme="light"] .dx-spoke-lab.hot{fill:var(--secondary)}
.dx-wedge{fill:rgba(181,37,85,.09);pointer-events:none;opacity:0;transition:opacity .25s var(--ease)}
.dx-wedge.on{opacity:1}
.dx-node{cursor:pointer;transition:opacity .25s var(--ease),transform .2s var(--bounce)}
.dx-node circle{transition:r .2s var(--bounce),stroke-width .2s var(--ease)}
.dx-node.dim{opacity:.14}
.dx-node.sel circle{stroke:var(--ink);stroke-width:2.5}
/* The core carries the Forward gradient as a soft glow rather than sitting as
   a black hole in the middle of the person's own map. The number is the thing
   in it, so it is large and solid; the label under it is deliberately quiet. */
/* .dx-core.n, NOT .dx-core .n. Both classes are on the SAME text element, so
   the descendant form matched nothing and the number rendered at the SVG
   default of 16 user units, about 11px on screen. It had never been styled.
   Seventh selector bug of this shape on the project, and the first where the
   rule simply never applied rather than applying to the wrong thing. */
.dx-core{text-anchor:middle}
.dx-core.n{font-family:var(--display);font-size:74px;font-weight:700;letter-spacing:-.045em;
  fill:var(--ink)}
.dx-core.l{font-size:17px;font-weight:650;letter-spacing:.09em;fill:var(--ink-3);
  text-transform:uppercase}
.dx-orbit-read{padding:18px}
.dx-orbit-key{gap:8px;font-size:12px}

.dx-orbit-side{display:flex;flex-direction:column;gap:14px;min-width:0}
.dx-lens{display:flex;gap:6px;flex-wrap:wrap}
.dx-lens button{padding:9px 14px;border-radius:999px;background:var(--raise-2);
  border:1px solid var(--hair);font:inherit;font-size:12.5px;font-weight:650;color:var(--ink-3);
  transition:all .2s var(--bounce)}
.dx-lens button:hover{background:var(--hair);color:var(--ink-2)}
.dx-lens button[aria-pressed="true"]{background:var(--secondary);border-color:var(--secondary);
  color:#fff}
.dx-orbit-read{padding:20px;border-radius:var(--r-md);background:var(--raise);
  border:1px solid var(--hair);min-height:190px}
.dx-orbit-read .k{display:block;font-size:11px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3);margin-bottom:9px}
/* direct child only, same reason as .mp-read above */
.dx-orbit-read > b{display:block;font-family:var(--display);font-size:19px;font-weight:650;
  letter-spacing:-.02em;line-height:1.25;margin-bottom:8px}
.dx-orbit-read p b{font-weight:700;color:var(--ink)}
.dx-orbit-read p{font-size:13.5px;color:var(--ink-2);line-height:1.55;margin-bottom:12px}
.dx-orbit-read .trg{display:inline-flex;align-items:center;gap:7px;padding:5px 11px;
  border-radius:999px;background:rgba(185,138,47,.18);color:var(--gold-soft,#E7C476);
  font-size:11.5px;font-weight:650}
html[data-theme="light"] .dx-orbit-read .trg{background:#F8EED8;color:var(--amber)}
.dx-orbit-key{display:flex;flex-direction:column;gap:9px;font-size:12.5px;color:var(--ink-3)}
.dx-orbit-key span{display:flex;align-items:center;gap:9px}
.dx-orbit-key i{width:13px;height:13px;border-radius:50%;display:inline-block;flex-shrink:0}
.dx-orbit-key i.use{background:var(--secondary)}
.dx-orbit-key i.avoided{background:var(--teal)}
.dx-orbit-key i.unknown{box-shadow:inset 0 0 0 1.5px var(--hair-2)}

.dx-field{margin-bottom:18px}
.dx-field-l{display:block;font-size:11.5px;font-weight:700;letter-spacing:.07em;
  text-transform:uppercase;color:var(--ink-3);margin-bottom:9px}
.dx-input{width:100%;padding:13px 16px;border-radius:var(--r-sm);border:1px solid var(--hair-2);
  background:var(--raise);color:var(--ink);font:inherit;font-size:15px}
.dx-input:focus{outline:none;border-color:var(--secondary)}
textarea.dx-input{min-height:88px;resize:vertical;line-height:1.5}

/* ---- the weekly review -------------------------------------------------- */
.dx-moved{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:11px}
.dx-move{padding:17px;border-radius:var(--r-md);background:var(--raise-2);border:1px solid var(--hair)}
.dx-move b{display:block;font-family:var(--display);font-size:26px;font-weight:700;
  letter-spacing:-.03em;line-height:1}
.dx-move .k{display:block;font-size:12.5px;color:var(--ink-2);margin-top:7px}
.dx-move .v{display:inline-flex;align-items:center;gap:5px;margin-top:9px;font-size:11.5px;
  font-weight:650}
.dx-move .v.up{color:var(--teal-soft)}
html[data-theme="light"] .dx-move .v.up{color:#0B7A6F}
.dx-move .v.down{color:var(--gold-soft,#E7C476)}
html[data-theme="light"] .dx-move .v.down{color:var(--amber)}

/* ---- a stat strip, used by more than one variant ------------------------ */
.dx-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px}
.dx-stat{padding:20px;border-radius:var(--r-md);background:var(--raise);border:1px solid var(--hair)}
.dx-stat b{display:block;font-family:var(--display);font-size:30px;font-weight:700;
  letter-spacing:-.035em;line-height:1}
.dx-stat span{display:block;font-size:12.5px;color:var(--ink-2);margin-top:8px;line-height:1.4}
.dx-stat .n{font-size:11.5px;color:var(--ink-3);margin-top:5px;display:block}

/* ---- a quiet note, and an honest empty ---------------------------------- */
.dx-note{display:flex;gap:9px;align-items:flex-start;margin-top:16px;font-size:12.5px;
  color:var(--ink-3);line-height:1.55}
.dx-note svg{flex-shrink:0;margin-top:1px}
.dx-note a{color:var(--secondary-soft);font-weight:600}
html[data-theme="light"] .dx-note a{color:var(--secondary)}
.dx-empty{border:1px dashed var(--hair);border-radius:var(--r-lg);padding:30px;text-align:center;
  color:var(--ink-3);font-size:14px;line-height:1.6}
.dx-empty b{display:block;color:var(--ink-2);font-weight:650;margin-bottom:6px;font-size:15px}

/* ---- the substance relationship board ----------------------------------- */
.dx-rel{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px}
.dx-relc{padding:22px;border-radius:var(--r-lg);background:var(--raise);border:1px solid var(--hair)}
.dx-relc-h{display:flex;align-items:center;gap:12px;margin-bottom:16px}
.dx-relc-h .ic{width:38px;height:38px;border-radius:12px;flex-shrink:0;display:grid;
  place-items:center;color:#fff;font-family:var(--display);font-weight:700;font-size:15px}
.dx-relc-h b{font-family:var(--display);font-size:18px;font-weight:650;letter-spacing:-.02em}
.dx-relc-h span{display:block;font-size:12px;color:var(--ink-3);margin-top:2px}
.dx-spark{display:flex;align-items:flex-end;gap:3px;height:46px;margin-bottom:14px}
.dx-spark i{flex:1;border-radius:3px 3px 1px 1px;background:var(--raise-2);min-height:2px;
  transition:height .8s var(--spring)}
.dx-spark i.on{background:var(--secondary)}
.dx-relc-rows{display:flex;flex-direction:column;gap:11px;align-items:flex-start}
.dx-relc-big{display:flex;align-items:baseline;gap:9px}
.dx-relc-big b{font-family:var(--display);font-size:30px;font-weight:700;letter-spacing:-.035em;
  line-height:1;color:var(--ink);font-variant-numeric:tabular-nums}
.dx-relc-big > span{font-size:13.5px;color:var(--ink-2);line-height:1.3}
/* The direction, as a pill, so it is read before it is parsed. Teal for fewer
   and gold for more, but the WORDS stay factual: "2 fewer", never "better". */
.dx-relc-delta{display:inline-flex;align-items:center;gap:6px;padding:5px 11px;border-radius:999px;
  font-size:12px;font-weight:650;line-height:1.3}
.dx-relc-delta.down{background:rgba(0,164,153,.2);color:var(--teal-soft)}
html[data-theme="light"] .dx-relc-delta.down{background:#DFF3F0;color:#0B7A6F}
.dx-relc-delta.up{background:rgba(185,138,47,.2);color:var(--gold-soft,#E7C476)}
html[data-theme="light"] .dx-relc-delta.up{background:#F8EED8;color:var(--amber)}
.dx-relc-delta.flat{background:var(--raise-2);color:var(--ink-3)}
.dx-relc-foot{font-size:12px;color:var(--ink-3)}

/* Content must never depend on an animation to be seen. */
@keyframes dxRise{from{opacity:0;transform:translateY(10px)}}
.dx-rise{animation:dxRise .45s var(--spring) both}
@media(prefers-reduced-motion:reduce){.dx-rise{animation:none}}
