@font-face {
  font-family: "Chivo Mono";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("fonts/chivo-mono/chivo-mono-latin-wght-normal.woff2") format("woff2");
}

/* werk's world with the house's red: graphit ground, weiss walls, mist machines, one red square */

:root {
  color-scheme: dark;
  --graphit: #1e2226;
  --night: #2a2f34;
  --weiss: #f6f6f3;
  --mist: #a0a7ae;
  --stahl: #5c636b;
  --rot: #e62e1e;
  --mono: "Chivo Mono", ui-monospace, Menlo, Consolas, monospace;
  --out: cubic-bezier(0.16, 1, 0.3, 1);
  --pad-x: 48px;
  --pad-y: 40px;
  --wall: 6px;
  --wall-gap: 3px;
}

@media (max-width: 719px) {
  :root {
    --pad-x: 16px;
    --pad-y: 24px;
    --wall: 5px;
    --wall-gap: 2.5px;
  }
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  background: var(--graphit);
  color: var(--weiss);
}

body {
  font-family: var(--mono);
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
}

.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.sheet {
  display: grid;
  place-items: center;
  min-height: 100svh;
  padding: var(--pad-y) var(--pad-x);
}

.frame {
  margin: 0;
}

.plan {
  display: block;
  -webkit-tap-highlight-color: transparent;
  overflow: visible;
  fill: none;
  stroke-linecap: butt;
  stroke-linejoin: miter;
  stroke-miterlimit: 8;
}

/* a wall in plan view is two lines: a wide weiss stroke with a graphit one inside it */
.plan .outer {
  stroke: var(--weiss);
  stroke-width: var(--wall);
}

/* the current: a red line laid between the wall's two lines, grown and drained by main.js */
.plan .charge {
  stroke: var(--rot);
  stroke-width: var(--wall);
}

.plan .inner {
  stroke: var(--graphit);
  stroke-width: var(--wall-gap);
}

.plan .tiles {
  stroke: var(--night);
  stroke-width: 1px;
}

.plan .axis {
  stroke: var(--stahl);
  stroke-width: 1px;
  stroke-dasharray: 14 4 2 4;
  opacity: 0.55;
}

.plan .bubble {
  stroke: var(--stahl);
  stroke-width: 1px;
}

.plan text {
  fill: var(--mist);
  stroke: none;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.04em;
  text-anchor: middle;
  dominant-baseline: central;
}

.plan .dim {
  stroke: var(--mist);
  stroke-width: 1px;
}

.plan .dim-label {
  fill: var(--stahl);
}

/* a door: the leaf, the hairline trace of its swing, and a red knob that says it can be handled */
.plan .door .leaf {
  stroke: var(--mist);
  stroke-width: 1.5px;
  transition: stroke 200ms var(--out);
}

.plan .door .swing {
  stroke: var(--stahl);
  stroke-width: 1px;
}

.plan .door .knob {
  fill: var(--rot);
}

.plan .door.hot .leaf {
  stroke: var(--weiss);
}

/* a built stretch of HAUS wall: solid like WERK's, laid over the hairlines as deliveries arrive;
   it turns red with its hall when the wall is charged */
.plan .built {
  stroke: var(--weiss);
  transition: stroke 200ms var(--out);
}

.plan .built.hot {
  stroke: var(--rot);
}

/* HAUS's sites, marked in place: a dashed boundary and a small label */
.plan .site-edge {
  stroke: var(--stahl);
  stroke-width: 1px;
  stroke-dasharray: 3 3;
}

.plan .site-label {
  fill: var(--mist);
  font-size: 8px;
  text-anchor: start;
}

.plan .site-tag {
  fill: var(--graphit);
}

/* the truck's planned route: a faint dashed hairline over the street grid */
.plan .route {
  stroke: var(--stahl);
  stroke-width: 1px;
  stroke-dasharray: 2 4;
}

.plan .title text {
  text-anchor: end;
  fill: var(--stahl);
}

/* equipment: mist lines, and faces filled with the ground so what stands behind is hidden */
.plan .icon {
  stroke: var(--mist);
  stroke-width: 1.1px;
  stroke-linejoin: round;
  transition: stroke 1400ms var(--out);
}

.plan .face {
  fill: var(--graphit);
}

/* the loader is easy to lose among the other thin mist lines: bolder at rest, so its
   silhouette reads at a glance */
.plan .icon.dig path {
  stroke-width: 1.6px;
}

/* working (a truck or a pala driving, a loader or a crane lifting) is drawn in the pen's red; it
   settles back to mist when the work stops */
.plan .icon.active {
  stroke: var(--rot);
  transition: none;
}

/* a charged hall lights its machines, each with a short cold-start flicker */
.plan .icon.lit {
  stroke: var(--weiss);
  transition-duration: 160ms;
}

.plan .icon.lit path {
  animation: flicker 520ms linear var(--lag, 0ms) both;
}

@keyframes flicker {
  0% { stroke: var(--mist); }
  10% { stroke: var(--weiss); }
  18% { stroke: var(--stahl); }
  34% { stroke: var(--weiss); }
  42% { stroke: var(--mist); }
  56%, 100% { stroke: var(--weiss); }
}

.plan .intro {
  opacity: 0;
  transition: opacity 900ms var(--out);
}

.plan.ready .intro {
  opacity: 1;
}

/* a drafting crosshair for the mouse: hairlines across the sheet, a pickbox, a red snap square when
   it is close enough to a wall to take it, and a red ring over a door */
@media (hover: hover) {
  .plan {
    cursor: none;
  }
}

.plan .cad {
  pointer-events: none;
}

.plan .hair {
  stroke: var(--stahl);
  stroke-width: 1px;
  opacity: 0.7;
}

.plan .pick {
  stroke: var(--weiss);
  stroke-width: 1px;
}

.plan .snap {
  stroke: var(--rot);
  stroke-width: 1.5px;
}


.plan .hand {
  stroke: var(--rot);
  stroke-width: 1.5px;
}

/* the bottom bar: the one way out on the left, flush with the plan's first wall; the sound switch
   on the right, flush with the last wall. items sit on one text baseline */
.tools {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 22px;
  margin: 8px var(--inset-r, 0px) 0 var(--inset, 0px);
}

/* the link: red at one tile's size, the page's one solid red mass */
.werk {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  min-height: 32px;
  color: var(--mist);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  --lift: 0deg;
  transition: color 240ms var(--out), --lift 420ms var(--out);
}

/* the link's mark: a wheeled loader in side view, in red lines (the one exception to the plan's
   top-down convention). the svg's bottom is the ground and sits on the text baseline; faces are
   filled with the ground so hidden lines stay hidden. on hover or focus the arm lifts and the
   bucket, kept level, rides the arm's arc above the cab roof with the label, its load */
/* scaled by main.js to the size of the pala in the plan; the stroke stays the plan's 1.1px */
.werk .sq {
  align-self: baseline;
  width: calc(68px * var(--mark, 0.45));
  height: calc(30px * var(--mark, 0.45));
  overflow: visible;
}

.werk .sq path {
  fill: var(--graphit);
  stroke: var(--rot);
  stroke-width: 1.1px;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

/* one animated angle drives the linkage: the arm turns up by it about its hinge (32, 14.9), the
   bucket turns back by it about the pin (52, 22) so it stays level, and the label follows the pin
   on the same arc: pin = hinge + 21.22 * (cos, sin)(19.54deg - lift), in the drawing's px. 47.3deg
   puts the bucket above the cab roof */
@property --lift {
  syntax: "<angle>";
  inherits: true;
  initial-value: 0deg;
}

.werk .sq .arm {
  transform-origin: 32px 14.9px;
  transform: rotate(calc(-1 * var(--lift)));
}

.werk .sq .bucket {
  transform-origin: 52px 22px;
  transform: rotate(var(--lift));
}

.werk .label {
  display: inline-block;
  transform: translate(
    calc(21.22px * var(--mark, 0.45) * (cos(19.54deg - var(--lift)) - cos(19.54deg))),
    calc(21.22px * var(--mark, 0.45) * (sin(19.54deg - var(--lift)) - sin(19.54deg)))
  );
}

.werk:hover,
.werk:focus-visible {
  --lift: 47.3deg;
}

.werk:hover,
.werk:focus-visible {
  color: var(--weiss);
}

/* the sound control is a switch, not a link: the link's type on the link's baseline, and a hairline
   track with a knob */
.mute {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  min-height: 32px;
  padding: 0;
  background: none;
  border: none;
  color: var(--mist);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 240ms var(--out);
}

/* the track sits on the text baseline, about as tall as the capitals */
.mute .switch {
  align-self: baseline;
  position: relative;
  width: 18px;
  height: 9px;
  border: 1px solid var(--stahl);
}

.mute .knob {
  position: absolute;
  top: 1px;
  left: 1px;
  width: 5px;
  height: 5px;
  background: var(--stahl);
  transition: left 200ms var(--out), background-color 200ms var(--out);
}

.mute[aria-pressed="true"] .knob {
  left: 10px;
  background: var(--rot);
}

.mute:hover,
.mute:focus-visible {
  color: var(--weiss);
}

.werk:focus-visible,
.mute:focus-visible {
  outline: 1px solid var(--weiss);
  outline-offset: 4px;
}

/* working beats lit: a machine at work stays red under a charged wall */
.plan .icon.active.lit {
  stroke: var(--rot);
}

.plan .icon.active.lit path {
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  .plan .icon.lit path {
    animation: none;
  }

  .plan .intro,
  .plan .icon,
  .plan .icon.lit,
  .werk,
  .mute,
  .mute .knob {
    transition: none;
  }
}
