/* ==================================================================
 * COLD AISLE -- PHASE 3: DESIGN SYSTEM
 * Option A from section 6 of COLDAISLE_BUILD.md: architectural drawing.
 *
 * The sheet is a general-arrangement plan of a data hall, drawn to real
 * drafting convention:
 *
 *   0.5px  construction lines, the grid, hatching, dimension lines
 *   1px    object lines -- anything actually built
 *   2px    cut lines -- walls and CRAC units, the things you cut through
 *
 * Rack type is shown by HATCHING DENSITY. Never by colour.
 *
 * THE ABSOLUTE RULE: colour is used for temperature and nothing else.
 * There are exactly five colours below -- four thermal tiers and the stock.
 * Everything else on this sheet is ink, or ink at an alpha. If you are about
 * to add a colour for a rack tier, a button, a state or a brand accent, the
 * whole idea collapses. Don't.
 *
 * The one place a thermal colour appears outside a rack is the brownout, and
 * that is not an exception: an over-power hall IS the hot state, so it is
 * drawn in t3 like anything else that is too hot.
 * ================================================================== */

/* ---- typeface ---- */

@font-face {
  font-family: "Archivo";
  src: url("../assets/fonts/archivo-variable.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("../assets/fonts/plex-mono-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("../assets/fonts/plex-mono-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* ---- tokens ---- */

:root {
  /* stock and ink */
  --stock:      #F4F2ED;
  --ink:        #1A1D21;
  --const:      rgba(26, 29, 33, .26);   /* construction line */
  --ink-soft:   rgba(26, 29, 33, .55);   /* an alpha of ink, not a new colour */

  /* temperature -- the only colour on this sheet */
  --t0: #5A8FC0;   /* cool     -- correctly aisled, cold column   */
  --t1: #C9A227;   /* warm     -- baseline                        */
  --t2: #D9631F;   /* hot      -- struggling                      */
  --t3: #B5352A;   /* critical -- bypassed, or the hall browned out */

  /* drafting line weights */
  --w-const: 0.5px;
  --w-object: 1px;
  --w-cut: 2px;

  /* geometry -- see Checkpoint A item 5 */
  --sheet-pad: 10px;
  --gap: 2px;
  --bay-h: 89px;      /* two 44px facing targets plus the 1px rule between */
  --label-w: 12px;
  --crac-w: 13px;
  --frame-pad: 4px;

  --sans: "Archivo", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", "Cascadia Mono", Menlo, monospace;

  color-scheme: light;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  background: var(--stock);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 13px;
  line-height: 1.35;
  -webkit-text-size-adjust: 100%;
}

body {
  padding: var(--sheet-pad);
  padding-bottom: calc(var(--sheet-pad) + env(safe-area-inset-bottom));
  max-width: 460px;
  margin: 0 auto;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

/* Archivo 600, uppercase, .12em tracking -- every label on the sheet. */
.label {
  font-family: var(--sans);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .12em;
}

/* IBM Plex Mono with tabular-nums -- every number on the sheet. */
.num {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* ---- sheet header ---- */

.sheet-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  border-bottom: var(--w-cut) solid var(--ink);
  padding-bottom: 5px;
}
.sheet-head .title { font-size: 13px; font-weight: 700; letter-spacing: .18em; }
.sheet-head .sub   { font-size: 8px; color: var(--ink-soft); text-align: right; }

/* ---- drift alarm: the preview must never lie ---- */

#drift {
  margin-top: 8px;
  padding: 7px 8px;
  border: var(--w-cut) solid var(--t3);
  color: var(--t3);
  font-size: 9px;
}

/* ---- rack schedule ---- */

.schedule {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--gap);
  margin: 9px 0 10px;
}
.schedule .cell {
  min-width: 0;
  border: var(--w-object) solid var(--ink);
  padding: 5px 7px 6px;
  min-height: 52px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1px;
}
.schedule .cell.next { border-color: var(--const); }
.schedule .key  { font-size: 7px; color: var(--ink-soft); }
.schedule .val  { font-size: 12px; letter-spacing: .08em; }
.schedule .sub  { font-size: 9px; color: var(--ink-soft); }
/* Rack names and stats must never widen the sheet. */
.schedule .val, .schedule .sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.schedule .cell.next .val { color: var(--ink-soft); }

/* ==================================================================
 * THE PLAN
 * ================================================================== */

.frame {
  border: var(--w-cut) solid var(--ink);   /* the hall envelope, cut */
  padding: var(--frame-pad);
}

.hall {
  display: grid;
  grid-template-columns:
    var(--label-w)          /* row bubbles A-D          */
    var(--crac-w)               /* CRAC 01, on the west wall */
    repeat(6, minmax(0, 1fr))   /* bays 1-6 -- minmax(0,..) or they refuse
                                   to shrink below their content and the
                                   whole sheet overflows 360px */
    var(--crac-w);              /* CRAC 02, on the east wall */
  grid-template-rows: 11px repeat(4, var(--bay-h));
  gap: var(--gap);
}

/* grid references, 1-6 and A-D */
.bubble {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: 8px;
  color: var(--ink-soft);
}

/* CRAC units: fixed to the walls, cut lines, never placed on */
.crac {
  grid-row: 2 / span 4;
  border: var(--w-cut) solid var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  background-image: repeating-linear-gradient(
    0deg, transparent 0 3px, var(--const) 3px 3.5px
  );
}
.crac .label {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-size: 7px;
  letter-spacing: .2em;
  color: var(--ink-soft);
}

/* ---- a bay ---- */

.bay {
  position: relative;
  min-width: 0;
  min-height: var(--bay-h);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: var(--w-const) solid var(--const);   /* construction line */
}

/* an empty bay the current rack cannot use */
.bay.blocked {
  background-image: repeating-linear-gradient(
    135deg, transparent 0 4px, var(--const) 4px 4.5px
  );
}
.bay.blocked .ref {
  margin: auto;
  font-family: var(--mono);
  font-size: 8px;
  color: var(--ink-soft);
}

/* the partner bay a 2-bay BLADE would also take */
.bay.ghost { outline: var(--w-object) dashed var(--ink); outline-offset: -3px; }

/* ---- the two preview numbers ----
 * Annotations, in ink. A delta is output, not temperature, so it takes no
 * colour: direction is carried by the sign, quality by the weight. */

.face {
  flex: 1;
  min-width: 0;
  min-height: 44px;               /* Checkpoint A item 5 */
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  border: 0;
  padding: 0 2px;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  font-family: var(--mono);
}
.face + .face { border-top: var(--w-const) solid var(--const); }
.face:hover, .face:focus-visible { background: rgba(26, 29, 33, .05); outline: 0; }
.face:active { background: rgba(26, 29, 33, .1); }
.face .arrow { font-size: 9px; color: var(--ink-soft); }
.face .n { font-size: 13px; font-variant-numeric: tabular-nums; }
.face .n.up   { font-weight: 600; }
.face .n.down { font-weight: 400; color: var(--ink-soft); }

/* ---- a placed rack ----
 * Object line, hatched by type, washed by temperature. */

.bay.filled {
  border: var(--w-object) solid var(--ink);
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 4px 2px;
  text-align: center;
}

/* hatching density is the rack type. never colour. */
.bay[data-rack="SLED"] {
  background-image: repeating-linear-gradient(45deg, transparent 0 7px, var(--const) 7px 7.5px);
}
.bay[data-rack="TRAINER"] {
  background-image: repeating-linear-gradient(45deg, transparent 0 4px, var(--const) 4px 4.6px);
}
.bay[data-rack="BLADE"] {
  background-image: repeating-linear-gradient(45deg, transparent 0 2px, var(--const) 2px 2.7px);
}
.bay[data-rack="BOOST"] {          /* cross-hatch: plant, not a rack */
  background-image:
    repeating-linear-gradient(45deg, transparent 0 5px, var(--const) 5px 5.5px),
    repeating-linear-gradient(-45deg, transparent 0 5px, var(--const) 5px 5.5px);
}

/* the thermal wash. this is the only colour on the drawing. */
.bay.filled::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--tier, transparent);
  opacity: .26;
  mix-blend-mode: multiply;
  pointer-events: none;
}
.bay[data-tier="0"] { --tier: var(--t0); }
.bay[data-tier="1"] { --tier: var(--t1); }
.bay[data-tier="2"] { --tier: var(--t2); }
.bay[data-tier="3"] { --tier: var(--t3); }

/* a bypass, struck through in ink the way a drawing voids something */
.bay.filled[data-bypass]::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background-image: linear-gradient(
    to top right,
    transparent calc(50% - .6px), var(--ink) calc(50% - .6px),
    var(--ink) calc(50% + .6px), transparent calc(50% + .6px)
  );
  pointer-events: none;
}
.bay.filled[data-bypass="2"]::before {
  background-image:
    linear-gradient(to top right, transparent calc(50% - .6px), var(--ink) calc(50% - .6px), var(--ink) calc(50% + .6px), transparent calc(50% + .6px)),
    linear-gradient(to bottom right, transparent calc(50% - .6px), var(--ink) calc(50% - .6px), var(--ink) calc(50% + .6px), transparent calc(50% + .6px));
}

.bay.filled .arrow { font-size: 15px; line-height: 1; position: relative; z-index: 2; }
.bay.filled .code  { font-size: 7px; letter-spacing: .1em; color: var(--ink-soft); position: relative; z-index: 2; }
.bay.filled .out   {
  font-family: var(--mono);
  font-weight: 600;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  position: relative;
  z-index: 2;
}

/* Racks snap into place. No easing out -- a machine put it there. */
@keyframes snap {
  from { transform: scale(1.09); opacity: 0; }
  55%  { opacity: 1; }
  to   { transform: none; opacity: 1; }
}
.bay.filled.placed { animation: snap 180ms linear both; }

/* ---- dimension line ---- */

.dim {
  display: grid;
  grid-template-columns:
    var(--label-w) var(--crac-w) repeat(6, minmax(0, 1fr)) var(--crac-w);
  gap: var(--gap);
  margin-top: 5px;
}
.dim-line {
  grid-column: 3 / span 6;
  position: relative;
  height: 15px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.dim-line::before {              /* the dimension line itself, construction weight */
  content: "";
  position: absolute;
  left: 0; right: 0; top: 50%;
  border-top: var(--w-const) solid var(--const);
}
.dim-line .tick {
  position: relative;
  width: var(--w-const);
  min-width: 1px;
  height: 11px;
  background: var(--const);
  transform: rotate(45deg);
  flex: none;
}
.dim-line .dim-text {
  position: relative;
  background: var(--stock);
  padding: 0 5px;
  font-size: 7px;
  color: var(--ink-soft);
}

/* ==================================================================
 * TITLE BLOCK
 * ================================================================== */

.titleblock {
  margin-top: 11px;
  border: var(--w-cut) solid var(--ink);
}
.tb-row { display: grid; grid-template-columns: 1fr auto auto; }
.tb-row + .tb-row { border-top: var(--w-object) solid var(--ink); }
.tb-cell {
  padding: 4px 8px 5px;
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.tb-cell + .tb-cell { border-left: var(--w-object) solid var(--ink); }
.tb-cell .key { font-size: 7px; color: var(--ink-soft); }
.tb-cell .val { font-family: var(--mono); font-size: 11px; }
/* The design condition this round is drawn to. Ink -- STRONG is not a colour. */
.tb-row.note { grid-template-columns: 1fr; }
.tb-row.note .tb-cell {
  flex-direction: row;
  align-items: baseline;
  justify-content: space-between;
  padding-top: 3px;
  padding-bottom: 4px;
}
.tb-row.note .val { font-size: 10px; letter-spacing: .1em; }

.tb-row.output { grid-template-columns: 1fr; }
.tb-row.output .tb-cell { flex-direction: row; align-items: baseline; justify-content: space-between; gap: 6px; }
.tb-cell .out {
  font-family: var(--mono);
  font-weight: 600;
  font-size: 27px;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
  margin-left: auto;
}
.tb-cell .unit { font-size: 8px; color: var(--ink-soft); }

/* ==================================================================
 * END OF ROUND
 * ================================================================== */

.over-panel {
  margin-top: 10px;
  border: var(--w-cut) solid var(--ink);
  padding: 10px;
}
.over-panel h2 { margin: 0 0 2px; font-size: 9px; }
.over-panel p  { margin: 0 0 9px; font-family: var(--mono); font-size: 10px; color: var(--ink-soft); }
.over-panel button {
  width: 100%;
  min-height: 46px;
  border: var(--w-cut) solid var(--ink);
  background: var(--ink);
  color: var(--stock);
  font-family: var(--sans);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .22em;
  cursor: pointer;
}
.over-panel button:active { background: var(--stock); color: var(--ink); }

/* ---- the share sheet ----
 * A completed floor plan with a number on it, legible to someone who has never
 * heard of the game. Shown before it is sent, so the player knows what goes out. */

.share-preview:not(:empty) {
  border: var(--w-object) solid var(--ink);
  margin-bottom: 8px;
  line-height: 0;
}
.share-preview canvas { width: 100%; height: auto; }

.share-actions {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: var(--gap);
  margin-bottom: 8px;
}
.over-panel button.secondary {
  min-height: 44px;
  background: transparent;
  color: var(--ink);
  border: var(--w-object) solid var(--ink);
  font-size: 10px;
  letter-spacing: .14em;
}
.over-panel button.secondary:active { background: var(--ink); color: var(--stock); }
.over-panel button.secondary[disabled] { color: var(--ink-soft); border-color: var(--const); }

footer {
  margin-top: 10px;
  font-size: 7px;
  color: var(--ink-soft);
}

/* ---- a machine put it there, but not if you asked it not to ---- */

@media (prefers-reduced-motion: reduce) {
  .bay.filled.placed { animation: none; }
  .power-track i { transition: none; }
}
