/* ============================================================
   Model Lab — activity component layer
   Loaded AFTER styles.css (the ported Hick's Law brand system).
   styles.css owns the tokens and the shell: .wrap .hero-banner
   .main-stage .card .btn .field .input .tabs .tablewrap .toast
   .chip .pill .metric .step .lead .muted .mono and the colour
   utilities .good .bad .danger .primary .tonal .ghost.

   Everything here is new vocabulary the three activities share.
   Same rules as the base: flat colour, squared corners, 2px ink
   borders, hard offset shadows with no blur, press-into-shadow.
   ============================================================ */

/* The [hidden] attribute is only `display:none` in the UA stylesheet, so any
   component rule that sets its own display (.vload uses grid, .clockbar uses
   flex, .field uses block) silently beats it and the element stays visible.
   This bit the 3D viewer: the loading overlay sat on top of a perfectly good
   render. Make hidden actually mean hidden, everywhere. */
[hidden]{ display:none !important; }

/* ---------- team identity strip ----------
   Sits under the hero on every activity page: who is playing, and
   a quiet way to change it without hunting through localStorage. */
.teamid{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:8px 12px; margin:0 0 14px;
  background:var(--surface); border:var(--border-w) solid var(--ink);
  border-radius:var(--radius-sm); box-shadow:var(--shadow-1);
}
.teamid .who{ font-weight:800; font-size:14px; letter-spacing:.01em; }
.teamid .mem{ color:var(--muted); font-size:12.5px; flex:1 1 140px; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.teamid .swap{
  background:none; border:0; padding:4px 6px; cursor:pointer;
  font:inherit; font-size:12px; font-weight:800; text-transform:uppercase;
  letter-spacing:.06em; color:var(--emerald-700); text-decoration:underline;
  text-underline-offset:3px;
}
.teamid .swap:hover{ color:var(--forest-700); }

/* ---------- section heading inside a card ---------- */
.hd{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:10px; flex-wrap:wrap; margin:0 0 10px;
}
.hd h2, .hd h3{ margin:0; }
.hd .side{ font-size:12px; font-weight:800; letter-spacing:.07em;
  text-transform:uppercase; color:var(--muted); }

/* ---------- callout ----------
   The brief, the rule, the warning. Gold = read this before you start. */
.callout{
  border:var(--border-w) solid var(--ink); border-left-width:7px;
  border-radius:var(--radius-xs); background:var(--surface-2);
  padding:11px 13px; margin:12px 0; font-size:14px; line-height:1.5;
}
.callout.gold  { border-left-color:var(--gold);    background:#fdf7ea; }
.callout.green { border-left-color:var(--emerald); background:var(--emerald-50); }
.callout.red   { border-left-color:var(--bad);     background:var(--bad-50); }
.callout b{ font-weight:800; }
.callout p{ margin:.45em 0 0; }
.callout p:first-child{ margin-top:0; }

/* ---------- stat grid ----------
   The Autopsy readout, and any place a set of hard numbers needs to
   sit together. Auto-fits: 2 up on a phone, 4+ on a laptop.        */
.stat-grid{
  display:grid; gap:8px; margin:12px 0;
  grid-template-columns:repeat(auto-fit,minmax(128px,1fr));
}
.stat{
  background:var(--surface); border:var(--border-w) solid var(--ink);
  border-radius:var(--radius-sm); box-shadow:var(--shadow-1);
  padding:9px 11px 10px; min-width:0;
}
.stat .lbl{
  display:block; font-size:10.5px; font-weight:800; letter-spacing:.1em;
  text-transform:uppercase; color:var(--muted); margin:0 0 3px;
}
.stat .v{
  display:block; font-size:22px; font-weight:900; line-height:1.1;
  color:var(--ink); font-variant-numeric:tabular-nums;
  overflow:hidden; text-overflow:ellipsis;
}
.stat .v small{ font-size:12px; font-weight:800; color:var(--muted); margin-left:2px; }
.stat .note{ display:block; font-size:11.5px; color:var(--muted); margin-top:3px; line-height:1.35; }
/* a stat that has tripped its threshold */
.stat.hot{ background:#fdf1ec; border-color:var(--bad); }
.stat.hot .v{ color:var(--bad); }
.stat.ok { background:var(--emerald-50); }
.stat.ok .v{ color:var(--emerald-700); }

/* ---------- meter ----------
   Budget bars. Fill turns gold at 80% and red past 100% so a team
   sees the overspend before they read the number.                  */
.meter-row{ margin:11px 0; }
.meter-head{
  display:flex; align-items:baseline; justify-content:space-between; gap:8px;
  font-size:12.5px; margin:0 0 4px;
}
.meter-head .name{ font-weight:800; text-transform:uppercase; letter-spacing:.07em; font-size:11px; }
.meter-head .val{ font-variant-numeric:tabular-nums; font-weight:800; }
.meter-head .val.over{ color:var(--bad); }
.meter{
  position:relative; height:15px; background:var(--cream-2);
  border:var(--border-w) solid var(--ink); border-radius:var(--radius-xs);
  overflow:hidden;
}
.meter-fill{
  height:100%; width:0; background:var(--emerald);
  transition:width .28s var(--ease), background-color .28s var(--ease);
}
.meter-fill.warn{ background:var(--gold); }
.meter-fill.over{ background:var(--bad); }
/* the 100% line, drawn inside the track so an over-budget fill runs past it */
.meter::after{
  content:""; position:absolute; inset-block:0; right:0; width:2px;
  background:var(--ink); opacity:.35;
}

/* ---------- pickable rows ----------
   The Budget Table asset list, and any multi-select list of options. */
.picklist{ display:flex; flex-direction:column; gap:7px; margin:12px 0; }
.pick{
  display:grid; grid-template-columns:auto 1fr auto; align-items:center; gap:10px;
  text-align:left; width:100%; cursor:pointer;
  background:var(--surface); border:var(--border-w) solid var(--ink);
  border-radius:var(--radius-sm); box-shadow:var(--shadow-1);
  padding:9px 11px; font:inherit; color:inherit;
  transition:transform .08s var(--ease), box-shadow .08s var(--ease),
             background-color .14s var(--ease);
}
.pick:hover{ background:var(--surface-2); }
.pick:active, .pick.is-press{ transform:translate(var(--sh-1),var(--sh-1)); box-shadow:none; }
.pick[aria-pressed="true"]{
  background:var(--emerald-50); border-color:var(--emerald-700);
  box-shadow:var(--sh-1) var(--sh-1) 0 var(--emerald-700);
}
.pick .box{
  width:19px; height:19px; flex:0 0 auto;
  border:var(--border-w) solid var(--ink); border-radius:var(--radius-xs);
  background:var(--surface); display:grid; place-items:center;
}
.pick[aria-pressed="true"] .box{ background:var(--emerald-700); border-color:var(--emerald-700); }
.pick .box svg{ width:12px; height:12px; stroke:#fff; stroke-width:3.2; fill:none;
  opacity:0; transition:opacity .12s var(--ease); }
.pick[aria-pressed="true"] .box svg{ opacity:1; }
.pick .nm{ font-weight:800; font-size:14px; line-height:1.25; min-width:0; }
.pick .sub{ display:block; font-weight:500; font-size:12px; color:var(--muted); margin-top:2px; }
.pick .fig{ font-variant-numeric:tabular-nums; font-size:12px; color:var(--muted);
  text-align:right; white-space:nowrap; }
.pick .fig b{ display:block; color:var(--ink); font-size:14px; }

/* ---------- single-choice options ----------
   Verdicts, licence answers, capture-method picks.                  */
.opts{ display:grid; gap:7px; margin:11px 0; }
.opts.row{ grid-template-columns:repeat(auto-fit,minmax(132px,1fr)); }
.opt{
  display:block; width:100%; text-align:left; cursor:pointer; font:inherit; color:inherit;
  background:var(--surface); border:var(--border-w) solid var(--ink);
  border-radius:var(--radius-sm); box-shadow:var(--shadow-1);
  padding:10px 12px;
  transition:transform .08s var(--ease), box-shadow .08s var(--ease),
             background-color .14s var(--ease);
}
.opt:hover{ background:var(--surface-2); }
.opt:active, .opt.is-press{ transform:translate(var(--sh-1),var(--sh-1)); box-shadow:none; }
.opt[aria-pressed="true"]{
  background:var(--forest-900); border-color:var(--forest-900); color:#fff;
  box-shadow:var(--shadow-1);
}
.opt[aria-pressed="true"] .sub{ color:rgba(255,255,255,.72); }
.opt .ttl{ display:block; font-weight:800; font-size:14px; line-height:1.25; }
.opt .sub{ display:block; font-size:12px; color:var(--muted); margin-top:2px; line-height:1.4; }
/* post-reveal marking */
.opt.right{ background:var(--emerald-50); border-color:var(--emerald-700);
  box-shadow:var(--sh-1) var(--sh-1) 0 var(--emerald-700); color:var(--ink); }
.opt.wrongpick{ background:var(--bad-50); border-color:var(--bad);
  box-shadow:var(--sh-1) var(--sh-1) 0 var(--bad); color:var(--ink); }

/* ---------- badges ---------- */
.badge{
  display:inline-flex; align-items:center; gap:5px;
  padding:2px 8px; border-radius:100px;
  border:2px solid var(--ink); background:var(--surface);
  font-size:11px; font-weight:800; letter-spacing:.05em; text-transform:uppercase;
  white-space:nowrap;
}
.badge.ship  { background:var(--emerald-50);  border-color:var(--emerald-700); color:var(--emerald-700); }
.badge.fix   { background:#fdf7ea;            border-color:var(--gold);        color:#8a5d12; }
.badge.reject{ background:var(--bad-50);      border-color:var(--bad);         color:var(--bad); }
.badge.wait  { background:var(--cream-2);     color:var(--muted); border-color:var(--line-2); }

/* ---------- 3D viewer frame ---------- */
.viewer{
  position:relative; width:100%; aspect-ratio:4/3; max-height:min(52vh,420px);
  background:
    linear-gradient(var(--cream-2) 1px, transparent 1px) 0 0/22px 22px,
    linear-gradient(90deg, var(--cream-2) 1px, transparent 1px) 0 0/22px 22px,
    var(--surface-2);
  border:var(--border-w) solid var(--ink); border-radius:var(--radius-sm);
  box-shadow:var(--shadow-2); overflow:hidden;
}
.viewer canvas{ display:block; width:100%; height:100%; touch-action:none; }
.viewer .vhint{
  position:absolute; left:8px; bottom:8px; z-index:2;
  background:rgba(22,36,29,.82); color:#fff;
  font-size:11px; font-weight:700; letter-spacing:.04em;
  padding:3px 8px; border-radius:var(--radius-xs); pointer-events:none;
}
.viewer .vload{
  position:absolute; inset:0; display:grid; place-items:center; z-index:3;
  background:var(--surface-2); font-size:13px; font-weight:800; color:var(--muted);
  text-align:center; padding:16px; gap:10px;
}

/* ---------- drop zone ---------- */
.drop{
  border:var(--border-w) dashed var(--ink); border-radius:var(--radius-sm);
  background:var(--surface-2); padding:22px 16px; text-align:center; cursor:pointer;
  transition:background-color .14s var(--ease), border-color .14s var(--ease);
}
.drop:hover, .drop.hot{ background:var(--emerald-50); border-color:var(--emerald-700); }
.drop .big{ display:block; font-weight:900; font-size:15px; margin-bottom:3px; }
.drop .sm { display:block; font-size:12.5px; color:var(--muted); }

/* ---------- data table ----------
   Wrap in .tablewrap (from styles.css) for horizontal scroll on phones. */
.dtl{ width:100%; border-collapse:collapse; font-size:13px; }
.dtl th, .dtl td{ padding:7px 9px; text-align:left; border-bottom:1px solid var(--line); }
.dtl thead th{
  font-size:10.5px; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
  color:var(--muted); border-bottom:var(--border-w) solid var(--ink); white-space:nowrap;
}
.dtl td.num, .dtl th.num{ text-align:right; font-variant-numeric:tabular-nums; white-space:nowrap; }
.dtl tbody tr:last-child td{ border-bottom:0; }
.dtl tbody tr:hover{ background:var(--surface-2); }
.dtl td.over{ color:var(--bad); font-weight:800; }
.dtl .team{ font-weight:800; }

/* ---------- key/value list ---------- */
.kv{ margin:9px 0; font-size:13.5px; }
.kv div{ display:flex; gap:9px; padding:5px 0; border-bottom:1px solid var(--line); }
.kv div:last-child{ border-bottom:0; }
.kv dt, .kv .k{ flex:0 0 40%; font-weight:800; color:var(--muted);
  font-size:11.5px; letter-spacing:.05em; text-transform:uppercase; padding-top:2px; }
.kv dd, .kv .v{ flex:1 1 auto; margin:0; }

/* ---------- reveal panel ----------
   The model answer. Hidden until the team has committed to a choice. */
.answer{
  margin-top:12px; border:var(--border-w) solid var(--forest-900);
  border-radius:var(--radius-sm); background:var(--emerald-50);
  box-shadow:var(--shadow-1); overflow:hidden;
}
.answer > h4{
  margin:0; padding:7px 12px; background:var(--forest-900); color:#fff;
  font-size:11px; font-weight:800; letter-spacing:.11em; text-transform:uppercase;
}
.answer .body{ padding:11px 13px; font-size:13.5px; line-height:1.55; }
.answer .body p{ margin:.5em 0 0; }
.answer .body p:first-child{ margin-top:0; }
.answer .body b{ font-weight:800; }
.answer .trap{
  margin-top:9px; padding-top:9px; border-top:2px dashed var(--line-2);
  font-size:13px;
}
.answer .trap b{ color:var(--gold); text-transform:uppercase; letter-spacing:.07em; font-size:11px; }

/* ---------- split layout ----------
   Text one side, viewer/figure the other. Stacks under 760px.       */
.split{ display:grid; gap:14px; }
@media (min-width:760px){
  .split{ grid-template-columns:1fr 1fr; align-items:start; }
  .split.wide-right{ grid-template-columns:minmax(0,4fr) minmax(0,6fr); }
  .split.wide-left { grid-template-columns:minmax(0,6fr) minmax(0,4fr); }
}

/* ---------- counter / timer ---------- */
.clockbar{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:7px 12px; margin:0 0 12px;
  background:var(--forest-900); color:#fff;
  border:var(--border-w) solid var(--ink); border-radius:var(--radius-sm);
  box-shadow:var(--shadow-1);
}
.clockbar .t{ font-variant-numeric:tabular-nums; font-weight:900; font-size:19px; letter-spacing:.02em; }
.clockbar .t.low{ color:var(--gold-soft); }
.clockbar .cap{ font-size:11px; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  color:rgba(255,255,255,.72); }

/* ---------- activity card (hub) ----------
   A whole card that is one big link. Lifts away from its shadow on
   hover, presses into it on click, same language as the buttons.   */
.card.act{
  display:block; text-decoration:none; color:inherit; position:relative;
  margin-bottom:12px;
  transition:transform .1s var(--ease), box-shadow .1s var(--ease);
}
.card.act:hover{ transform:translate(-1px,-1px); box-shadow:var(--shadow-3); }
.card.act:active{ transform:translate(var(--sh-1),var(--sh-1)); box-shadow:none; }
.card.act .badge{ position:absolute; top:12px; right:12px; }
.card.act h2{ margin:0 6px .3em 0; padding-right:96px; font-size:19px; }
.card.act .lead{ margin:0 0 .4em; }

/* ---------- small print ---------- */
.fine{ font-size:12px; color:var(--muted); line-height:1.5; }
.fine a{ color:var(--emerald-700); }

/* ---------- asset listing card (Can I Ship This?) ----------
   Reads like a marketplace listing without imitating a real one.  */
.listing .lhead{
  display:flex; align-items:flex-start; justify-content:space-between; gap:10px; flex-wrap:wrap;
}
.listing .lhead h2{ margin:0; font-size:20px; line-height:1.2; flex:1 1 220px; min-width:0; }
.listing .lhead .badge{ flex:0 0 auto; margin-top:3px;
  background:var(--forest-900); color:#fff; border-color:var(--forest-900); }
.listing .lauthor{ margin:.35em 0 .1em; font-size:14px; color:var(--ink-2); }
.listing .lauthor b{ font-weight:800; }
.listing .ldetails{
  list-style:none; margin:11px 0; padding:0;
  display:flex; flex-wrap:wrap; gap:6px;
}
.listing .ldetails li{
  font-size:11.5px; font-weight:700; padding:3px 9px;
  background:var(--cream-2); border:1px solid var(--line-2);
  border-radius:100px; color:var(--ink-2); white-space:nowrap;
}
.listing .lsmall{
  margin:11px 0 0; padding:10px 12px;
  background:var(--surface-2); border:var(--border-w) solid var(--line-2);
  border-left-width:7px; border-left-color:var(--gold);
  border-radius:var(--radius-xs);
  font-size:13px; line-height:1.5; font-style:italic; color:var(--ink-2);
}

/* attribution comparison inside a reveal */
.attrcmp{
  margin:.5em 0 0; padding:7px 10px; font-size:12.5px; line-height:1.45;
  background:var(--surface); border:2px solid var(--line-2); border-radius:var(--radius-xs);
}
.attrcmp.model{ background:var(--emerald-50); border-color:var(--emerald-700); }
.attrcmp .lbl{
  display:block; font-size:10px; font-weight:800; letter-spacing:.1em;
  text-transform:uppercase; color:var(--muted); margin-bottom:3px;
}

/* textarea shares the .input look */
textarea.input{ resize:vertical; min-height:70px; line-height:1.5; font:inherit; }

/* .swap works as a link as well as a button */
a.swap{ text-decoration:underline; text-underline-offset:3px; }

/* ---------- requirements checklist (Budget Table) ---------- */
.reqlist{ list-style:none; margin:10px 0 0; padding:0; }
.reqlist li{
  font-size:13.5px; padding:3px 0 3px 20px; position:relative; color:var(--ink-2);
}
.reqlist li::before{
  content:""; position:absolute; left:4px; top:11px;
  width:6px; height:6px; border-radius:50%; background:var(--line-2);
}
.reqlist.live li{ padding-left:24px; }
.reqlist.live li::before{ display:none; }
.reqlist.live .tick{
  position:absolute; left:0; top:2px; width:17px; height:17px;
  display:grid; place-items:center; font-size:11px; font-weight:900;
  border:2px solid var(--line-2); border-radius:var(--radius-xs);
  background:var(--surface); color:transparent;
}
.reqlist.live li.met .tick{ background:var(--emerald-700); border-color:var(--emerald-700); color:#fff; }
.reqlist.live li.met{ color:var(--ink); }
.reqlist.live li.unmet{ color:var(--muted); }
.reqlist.live li b{ font-weight:800; }

/* sticky meter block while scrolling the asset list */
.card.meters{ position:sticky; top:6px; z-index:5; }
@media (max-width:759px){ .card.meters{ position:static; } }

.catname{
  margin:16px 0 7px; font-size:11px; font-weight:800; letter-spacing:.11em;
  text-transform:uppercase; color:var(--accent-d,var(--forest-700));
}
.catname:first-child{ margin-top:2px; }

.vtag{
  display:inline-block; font-style:normal; font-size:9.5px; font-weight:800;
  letter-spacing:.08em; text-transform:uppercase; vertical-align:1px;
  padding:1px 6px; margin-left:5px; border-radius:100px;
  background:var(--emerald-100); color:var(--emerald-700); border:1px solid var(--emerald-700);
}
.pick[aria-pressed="true"] .vtag{ background:#fff; }

.fine.okmsg{ color:var(--emerald-700); font-weight:700; }

/* totals row on a data table */
.dtl tfoot td{ border-top:var(--border-w) solid var(--ink); padding-top:8px; }

/* ---------- distribution bars (instructor board) ---------- */
.casedist{ margin:14px 0 16px; }
.distrow{
  display:grid; grid-template-columns:minmax(96px,150px) 1fr 30px;
  align-items:center; gap:9px; margin:4px 0; font-size:12.5px;
}
.distrow .dl{ color:var(--ink-2); font-weight:600; }
.distrow .dbar{
  height:14px; background:var(--cream-2);
  border:var(--border-w) solid var(--ink); border-radius:var(--radius-xs); overflow:hidden;
}
.distrow .dbar i{ display:block; height:100%; background:var(--line-2); }
.distrow .dbar i.ok{ background:var(--emerald); }
.distrow .dbar i.no{ background:var(--bad); }
.distrow .dn{ text-align:right; font-variant-numeric:tabular-nums; font-weight:800; }

/* ============================================================
   DESKTOP FITTING
   The base sheet is mobile-first and stops at a 720px breakpoint
   with a 960px cap, which leaves a laptop mostly empty. These
   blocks widen the shell and turn the working screens into real
   two-column layouts. Nothing below 1100px is touched.
   ============================================================ */
@media (min-width:1100px){
  /* a laptop-width column instead of a phone column with margins */
  .wrap{ max-width:1200px; padding:26px 28px 48px; }

  /* content sits at the top; the base sheet centres it vertically,
     which strands short screens in the middle of a tall viewport */
  .main-stage{ justify-content:flex-start; }

  body{ font-size:16px; }

  .hero-banner{ padding:20px 26px; }
  .card{ padding:26px 28px; }

  /* headings get room to breathe at this width */
  .card h1{ font-size:30px; }
  .card h2{ font-size:23px; }

  /* stat tiles stop being phone-sized */
  .stat-grid{ gap:10px; grid-template-columns:repeat(auto-fit,minmax(160px,1fr)); }
  .stat .v{ font-size:24px; }

  /* the hub: three activities side by side, equal height */
  .actgrid{ display:grid; grid-template-columns:repeat(3,1fr); gap:14px; align-items:stretch; }
  /* the base sheet gives .card a margin-top that the first grid item
     picks up differently — zero it so all three tops line up */
  .actgrid .card.act{ margin:0; display:flex; flex-direction:column; }
  .actgrid .card.act h2{ padding-right:0; margin-top:6px; }
  .actgrid .card.act .badge{ position:static; align-self:flex-start; }
  .actgrid .card.act .fine{ margin-top:auto; padding-top:10px; }

  /* the Budget build screen: controls left, catalogue right.
     DOM order stays meters -> assets -> submit so the phone
     layout is still correct; desktop places them explicitly. */
  .worksplit{
    grid-template-columns:minmax(0,380px) minmax(0,1fr);
    /* row 1 pinned to the meters; row 2 absorbs the tall asset column,
       otherwise the spanning item inflates row 1 and strands the
       submit card halfway down the page */
    grid-template-rows:max-content 1fr;
    align-items:start;
  }
  .worksplit > .meters     { grid-column:1; grid-row:1; }
  .worksplit > .assets     { grid-column:2; grid-row:1 / span 2; margin-top:0; }
  .worksplit > .submitcard { grid-column:1; grid-row:2; align-self:start; }

  /* the catalogue is long — two columns of it fit comfortably */
  .assets .picklist{ display:grid; grid-template-columns:1fr 1fr; gap:8px; }

  /* the viewer can afford to be big on a laptop */
  .viewer{ max-height:min(60vh,520px); }

  /* verdict rows sit side by side rather than stacking */
  .opts.row{ grid-template-columns:repeat(3,1fr); }

  /* a form or a short brief should not stretch a single input across
     the full width of a 1380px page — cap those cards instead */
  .card.narrow{ max-width:680px; }
  .card.narrow .btnrow{ justify-content:flex-start; }
}

@media (min-width:1500px){
  .wrap{ max-width:1380px; }
  .worksplit{ grid-template-columns:minmax(0,420px) minmax(0,1fr); }
  .assets .picklist{ grid-template-columns:repeat(3,1fr); }
  .viewer{ max-height:min(64vh,600px); }
}

/* the Budget working area — one column until the desktop rules above */
.worksplit{ display:grid; gap:16px; }

/* ---------- print: the plenary handout ---------- */
@media print{
  .hero-banner, .teamid, .btnrow, .clockbar, .drop{ display:none !important; }
  body{ background:#fff; }
  .card{ box-shadow:none; break-inside:avoid; }
  .answer{ box-shadow:none; }
}
