/* ---------------------------------------------------------------------------
   Last Dose, a 380 x 460 widget for lifescienceweekly.com.

   Bust-a-Move on a culture plate. Colonies grow down the agar and you dose them
   from a pipette; three or more of a kind clear together, and anything left
   unattached to the growth clears with them.

   The one rule that is not Bust-a-Move is RESISTANCE, and here it is not a
   metaphor: left alone a colony turns resistant and becomes another species, so
   a dose you plan for too long stops working. It always marks the colony first,
   and clearing it in time stops the change, which is what makes it a decision
   rather than a tax on thinking.

   The board is the dish: agar above the breakpoint, bench below it. The band of
   confluent growth at the top is the thing that advances, so when it spreads
   there is something visibly moving rather than bubbles drifting in a void.

   A tall narrow frame is the shape this game already wants, the same piece of
   luck Frogger gave us on Callout Repair.

   Namespaced .ld- so it can drop into a page that already ships its own
   css/styles.css without either side bleeding.
--------------------------------------------------------------------------- */

.ld-widget, .ld-widget * { box-sizing: border-box; margin: 0; padding: 0; }

/* An author display rule outranks the UA sheet's [hidden]{display:none}. */
.ld-widget [hidden] { display: none !important; }

.ld-widget {
  --brand:   #0d9488;
  --brand-dk:#0f766e;
  --lit:     #5eead4;
  --lit-dim: #2dd4bf;
  --bad:     #fb7185;
  --bg:      #0b1512;
  --panel:   #13201c;
  --line:    rgba(255,255,255,.09);
  --line-lt: rgba(255,255,255,.17);
  --ink:     #e6f2ef;
  --muted:   #7f9a93;

  position: relative;
  width: 380px;
  height: 460px;
  padding: 11px;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}
.ld-widget:focus { outline: none; }
.ld-widget:focus-visible { outline: 2px solid var(--lit); outline-offset: 2px; }

/* ---- header ---- */
.ld-head { flex: none; height: 34px; display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.ld-brand { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.ld-name { font-size: 14px; font-weight: 700; letter-spacing: -.01em; white-space: nowrap; }
.ld-site {
  font-size: 8px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ld-chip {
  flex: none; border: 1px solid var(--line-lt); background: rgba(255,255,255,.04);
  color: var(--ink); border-radius: 999px; height: 21px; padding: 0 9px;
  font: 600 9px/1 'Inter', sans-serif; letter-spacing: .06em; text-transform: uppercase;
  cursor: pointer; white-space: nowrap; display: inline-flex; align-items: center;
}
.ld-chip:hover { border-color: var(--lit); color: var(--lit); }

/* ---- board ---- */
.ld-board {
  flex: none; position: relative; align-self: center; margin-top: 8px;
  width: 358px; height: 316px;
  border: 1px solid var(--line); border-radius: 6px; overflow: hidden; background: #081210;
  touch-action: none; cursor: crosshair;
}
.ld-board canvas { display: block; width: 358px; height: 316px; }

/* ---- readouts ---- */
.ld-panel { flex: none; height: 42px; margin-top: 7px; display: flex; gap: 6px; }
.ld-cell {
  flex: 1 1 0; min-width: 0; border: 1px solid var(--line); border-radius: 7px; background: var(--panel);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
}
.ld-lab { font-size: 7px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.ld-val { font-size: 13px; font-weight: 700; letter-spacing: -.01em; font-variant-numeric: tabular-nums; }
.ld-val.ld-low { color: var(--bad); }
.ld-val.ld-good { color: var(--lit); }
.ld-pips { display: flex; gap: 4px; align-items: center; height: 13px; }
.ld-pip { width: 7px; height: 9px; border-radius: 2px; background: var(--lit); }
.ld-pip.ld-gone { background: transparent; border: 1px solid rgba(255,255,255,.2); }

/* ---- ticker ---- */
.ld-tick {
  flex: none; height: 15px; margin-top: 7px;
  font-size: 9.5px; line-height: 15px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ld-tick b { color: var(--ink); font-weight: 600; }

/* ---- cards ---- */
/* Starts below the header. At inset 0 the scrim covers the mode chip, so the
   screen cannot be changed while any card is up, which is exactly when a
   player wants to change it. 45px is 11px padding plus the 34px header. */
.ld-over {
  position: absolute; top: 45px; right: 0; bottom: 0; left: 0; z-index: 5;
  display: flex; align-items: center; justify-content: center; padding: 14px;
  background: rgba(11,21,18,.94); backdrop-filter: blur(3px);
}
.ld-card { width: 100%; text-align: center; }
.ld-kick {
  font-size: 8px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--lit); margin-bottom: 7px;
}
.ld-kick.ld-kick-bad { color: var(--bad); }
.ld-title { font-size: 19px; font-weight: 700; letter-spacing: -.02em; line-height: 1.15; }
.ld-sub { font-size: 10.5px; line-height: 1.5; color: var(--muted); margin-top: 8px; }
.ld-sub b { color: var(--ink); font-weight: 600; }
.ld-note { font-size: 9px; line-height: 1.45; color: var(--muted); margin-top: 9px; }

.ld-facts { margin-top: 10px; display: flex; flex-direction: column; gap: 5px; text-align: left; }
.ld-fact { display: flex; gap: 6px; font-size: 9px; line-height: 1.4; color: var(--muted); }
.ld-fact i { flex: none; font-style: normal; font-weight: 700; color: var(--lit); }
.ld-fact b { color: var(--ink); font-weight: 600; }

.ld-lines { margin-top: 11px; display: flex; flex-direction: column; gap: 4px; }
.ld-row {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  border: 1px solid var(--line); border-radius: 6px; background: var(--panel);
  padding: 5px 8px; font-size: 9.5px;
}
.ld-row span:first-child { color: var(--muted); }
.ld-row b { font-weight: 700; font-variant-numeric: tabular-nums; }
.ld-row b.ld-hit { color: var(--lit); }
.ld-row b.ld-miss { color: var(--bad); }

.ld-go {
  margin-top: 12px; border: none; border-radius: 7px; background: var(--brand); color: #fff;
  height: 33px; padding: 0 18px; font: 700 11.5px/1 'Inter', sans-serif; letter-spacing: .03em; cursor: pointer;
}
.ld-go:hover { background: var(--brand-dk); }
.ld-go.ld-ghost { background: transparent; border: 1px solid var(--line-lt); color: var(--ink); height: 29px; font-size: 10.5px; }
.ld-go.ld-ghost:hover { border-color: var(--lit); color: var(--lit); }
.ld-rowc { display: flex; gap: 7px; justify-content: center; align-items: center; }

.ld-opts { display: flex; flex-direction: column; gap: 5px; margin-top: 11px; }
.ld-opt {
  border: 1px solid var(--line-lt); border-radius: 6px; background: var(--panel); color: var(--ink);
  text-align: left; padding: 7px 9px; font: 500 10px/1.35 'Inter', sans-serif; cursor: pointer;
}
.ld-opt:hover { border-color: var(--lit); }
.ld-opt.ld-right { border-color: var(--lit); background: rgba(45,212,191,.18); }
.ld-opt.ld-wrong { border-color: var(--bad); background: rgba(251,113,133,.12); }

.ld-form { margin-top: 12px; display: flex; gap: 6px; }
.ld-in {
  flex: 1 1 auto; min-width: 0; border: 1px solid var(--line-lt); border-radius: 6px;
  background: rgba(255,255,255,.05); color: var(--ink); height: 30px; padding: 0 9px;
  font: 500 10.5px/1 'Inter', sans-serif;
}
.ld-in::placeholder { color: var(--muted); }
.ld-in:focus { outline: none; border-color: var(--lit); }
.ld-send {
  flex: none; border: none; border-radius: 6px; background: var(--brand); color: #fff;
  height: 30px; padding: 0 12px; font: 700 10px/1 'Inter', sans-serif; cursor: pointer;
}
.ld-send:hover { background: var(--brand-dk); }
.ld-msg { font-size: 9px; line-height: 1.45; color: var(--muted); margin-top: 7px; }
.ld-msg.ld-err { color: var(--bad); }
.ld-msg.ld-done { color: var(--lit); }

/* ---- keycaps on the start card ---- */
.ld-keys { display: flex; justify-content: center; flex-wrap: wrap; gap: 5px 7px; margin-top: 11px; }
.ld-hintkey { display: flex; align-items: center; gap: 4px; }
.ld-cap {
  min-width: 19px; height: 19px; padding: 0 5px;
  border: 1px solid var(--line-lt); border-radius: 4px; background: rgba(255,255,255,.05);
  font-size: 9.5px; font-weight: 600; line-height: 17px; text-align: center;
}
.ld-caplab { font-size: 8.5px; color: var(--muted); }

/* ---- screen-cleared plate ---- */
.ld-plate {
  position: absolute; top: 45px; right: 0; bottom: 0; left: 0; z-index: 4;
  display: flex; align-items: center; justify-content: center; pointer-events: none;
}
.ld-plateIn {
  border: 1px solid var(--lit); border-radius: 9px; background: rgba(11,21,18,.9);
  padding: 13px 20px; text-align: center; animation: ld-plate .42s cubic-bezier(.2,1.5,.4,1);
}
@keyframes ld-plate { 0% { transform: scale(.7); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
.ld-plateK { font-size: 8px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--lit); }
.ld-plateT { font-size: 17px; font-weight: 700; letter-spacing: -.02em; margin-top: 5px; }
.ld-plateS { font-size: 9px; color: var(--muted); margin-top: 5px; }

/* ---- tooltips ---- */
/* Native title= sits on an uncontrollable browser delay of about a second. */
.ld-widget [data-tip] { position: relative; }
.ld-widget [data-tip]::after {
  content: attr(data-tip);
  position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%);
  width: max-content; max-width: 172px;
  border: 1px solid var(--line-lt); border-radius: 5px; background: #07100e;
  padding: 5px 7px; font: 500 8.5px/1.35 'Inter', sans-serif; color: var(--ink); text-align: center;
  /* Hosts set nowrap, uppercase and letter spacing, and the tooltip inherits
     all three, so without these it refuses to wrap and shouts. */
  white-space: normal; text-transform: none; letter-spacing: normal;
  pointer-events: none; opacity: 0; z-index: 9;
  transition: opacity .1s ease .45s;
}
.ld-widget [data-tip]:hover::after,
.ld-widget [data-tip]:focus-visible::after { opacity: 1; transition-delay: .09s; }
/* A centred tooltip on an outer control is clipped by the widget's own
   overflow: hidden, so the outer ones anchor inward. */
.ld-chip[data-tip]::after { top: calc(100% + 6px); bottom: auto; left: auto; right: 0; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .ld-widget [data-tip]::after { transition: none; }
  .ld-plateIn { animation: none; }
}

/* ---------------------------------------------------------------------------
   Homepage slot.

   The markup for this widget is inlined in index.html inside .hero__sidebar,
   replacing the Top Stories list. .hero__grid is already `1fr 380px`, so at
   full width the widget fits the slot exactly and nothing below applies.
   ------------------------------------------------------------------------ */

/* styles.css hides .hero__sidebar at <=1024px, where it held Top Stories. The
   game is meant to show on tablets and phones, so that is reverted here.
   .hero__grid is already a single column at this width, and the widget simply
   stacks under the cover story. */
@media (max-width: 1024px) {
  .hero__grid .hero__sidebar { display: flex; }
}

/* Two levels on purpose. .ld-fit is the LAYOUT box and is sized to the scaled
   dimensions; .ld-widget keeps its real 380 x 460 and is transformed down to
   fill it. Putting the transform on .ld-fit itself does not work: a transform
   leaves the layout box at full size, so a 380px box would stay 380px inside a
   narrower grid track and push the page sideways. Sizing the box and scaling
   the contents means the track only ever sees the scaled width. */
.ld-fit {
  --ld-s: 1;
  width:  calc(380px * var(--ld-s));
  height: calc(460px * var(--ld-s));
  margin-inline: auto;
}

.ld-fit > .ld-widget {
  transform: scale(var(--ld-s));   /* --ld-s inherits from .ld-fit */
  transform-origin: top left;
}

/* The widget is a fixed 380px block whose copy was measured at that width, and
   .ld-tick is white-space: nowrap. Reflowing it would truncate the ticker, so
   it is scaled instead. Each step is the largest scale that still fits 380px
   inside the viewport minus the container's 48px of padding, so the widget
   never overflows and never triggers a sideways scroll. Unscaled above 435px,
   where the widget clears the container by 8px. */
@media (max-width: 435px) { .ld-fit { --ld-s: .94; } }  /* 409-435 */
@media (max-width: 408px) { .ld-fit { --ld-s: .89; } }  /* 390-408 */
@media (max-width: 389px) { .ld-fit { --ld-s: .85; } }  /* 374-389 */
@media (max-width: 373px) { .ld-fit { --ld-s: .81; } }  /* 359-373 */
@media (max-width: 358px) { .ld-fit { --ld-s: .73; } }  /* 329-358 */
@media (max-width: 328px) { .ld-fit { --ld-s: .67; } }  /* to 320   */
