/* Classroom Traffic Light. The whole signal head is CSS: --L is a lens's
   diameter and everything else is a fraction of it, so the light keeps its
   proportions from a small Board widget to a 4K projector. */

.tl {
  --k: 1;
  --L: calc(min(20.5cqh, 21cqw) * var(--k));
  display: grid; place-items: center; padding: 5cqmin 4cqmin 7cqmin;
  overflow: hidden;
}
.tl.no-labels { --L: calc(min(20.5cqh, 60cqw) * var(--k)); }
.tl[data-orient="horizontal"] { --L: calc(min(20.5cqw, 34cqh) * var(--k)); }
.tl[data-orient="horizontal"].no-labels { --L: calc(min(21cqw, 52cqh) * var(--k)); }
/* Room at the top for the countdown chip. */
.tl.is-auto { --k: .88; padding-top: calc(clamp(8px, 2.4cqmin, 26px) + clamp(30px, 8cqmin, 80px)); }

.tl-scene { display: flex; align-items: stretch; gap: calc(var(--L) * .3); }
.tl[data-orient="horizontal"] .tl-scene { flex-direction: column; align-items: center; gap: calc(var(--L) * .2); }

/* ---- housing ---- */
.tl-head {
  --pad: calc(var(--L) * .17);
  --cell: calc(var(--L) * 1.24);
  position: relative; flex: none; display: grid;
  grid-template-rows: repeat(3, var(--cell)); grid-template-columns: calc(var(--L) * 1.2);
  place-items: center; padding: var(--pad) calc(var(--pad) * 1.05);
  border-radius: calc(var(--L) * .26);
  background:
    linear-gradient(to bottom,
      transparent calc(var(--pad) + var(--cell) - 1px), rgba(0, 0, 0, .55) calc(var(--pad) + var(--cell) - 1px),
      rgba(255, 255, 255, .06) calc(var(--pad) + var(--cell) + 1px), transparent calc(var(--pad) + var(--cell) + 2px),
      transparent calc(var(--pad) + var(--cell) * 2 - 1px), rgba(0, 0, 0, .55) calc(var(--pad) + var(--cell) * 2 - 1px),
      rgba(255, 255, 255, .06) calc(var(--pad) + var(--cell) * 2 + 1px), transparent calc(var(--pad) + var(--cell) * 2 + 2px)),
    linear-gradient(90deg, #0f1114 0%, #2b3037 14%, #20242a 36%, #1a1d22 64%, #2a2f36 86%, #0d0f12 100%);
  box-shadow:
    inset 0 calc(var(--L) * .02) 0 rgba(255, 255, 255, .09),
    inset 0 calc(var(--L) * -.03) calc(var(--L) * .06) rgba(0, 0, 0, .65),
    0 0 0 1px rgba(0, 0, 0, .55),
    0 calc(var(--L) * .1) calc(var(--L) * .22) rgba(0, 0, 0, .32),
    0 calc(var(--L) * .03) calc(var(--L) * .05) rgba(0, 0, 0, .3);
}
.tl[data-orient="horizontal"] .tl-head {
  grid-template-rows: calc(var(--L) * 1.24); grid-template-columns: repeat(3, var(--cell));
  padding: calc(var(--pad) * 1.15) var(--pad) calc(var(--pad) * .95);
  background:
    linear-gradient(to right,
      transparent calc(var(--pad) + var(--cell) - 1px), rgba(0, 0, 0, .55) calc(var(--pad) + var(--cell) - 1px),
      rgba(255, 255, 255, .06) calc(var(--pad) + var(--cell) + 1px), transparent calc(var(--pad) + var(--cell) + 2px),
      transparent calc(var(--pad) + var(--cell) * 2 - 1px), rgba(0, 0, 0, .55) calc(var(--pad) + var(--cell) * 2 - 1px),
      rgba(255, 255, 255, .06) calc(var(--pad) + var(--cell) * 2 + 1px), transparent calc(var(--pad) + var(--cell) * 2 + 2px)),
    linear-gradient(180deg, #2c3138 0%, #20242a 30%, #1a1d22 70%, #0d0f12 100%);
}
/* Dark mode: a faint rim so the housing still reads against a dark stage. */
:root[data-theme="dark"] .tl-head { outline: 1px solid rgba(255, 255, 255, .07); outline-offset: 0; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .tl-head { outline: 1px solid rgba(255, 255, 255, .07); } }

/* ---- one lamp: bezel, lens, visor ---- */
.tl-lamp {
  --lens: #ff3b30;
  position: relative; width: var(--L); height: var(--L); padding: 0; border: 0; border-radius: 50%;
  background: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.tl-lamp[data-c="amber"] { --lens: #ffb11a; }
.tl-lamp[data-c="green"] { --lens: #17df8a; }
.tl-lamp:focus-visible { outline: none; }
.tl-lamp:focus-visible .tl-bezel { box-shadow: 0 0 0 calc(var(--L) * .03) #fff, 0 0 0 calc(var(--L) * .06) var(--cat); }

/* The glow that spills onto the housing around a lit lens. */
.tl-lamp::before {
  content: ""; position: absolute; inset: -42%; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, color-mix(in srgb, var(--lens) 38%, transparent) 0, color-mix(in srgb, var(--lens) 12%, transparent) 45%, transparent 68%);
  opacity: 0; transition: opacity .25s;
}
.tl-lamp.is-on::before { opacity: 1; }

.tl-bezel {
  position: absolute; inset: -7%; border-radius: 50%;
  background: radial-gradient(circle, #040506 64%, #262a30 70%, #121417 84%, #2a2f36 100%);
  box-shadow: inset 0 calc(var(--L) * .02) calc(var(--L) * .04) rgba(0, 0, 0, .9), 0 1px 0 rgba(255, 255, 255, .05);
}

.tl-lens {
  position: absolute; inset: 0; border-radius: 50%; overflow: hidden;
  background:
    repeating-radial-gradient(circle at 50% 50%, rgba(255, 255, 255, .05) 0 1.1%, transparent 1.1% 4.6%),
    radial-gradient(circle at 50% 46%, color-mix(in srgb, var(--lens) 38%, #0b0b0c) 0%, color-mix(in srgb, var(--lens) 22%, #070708) 60%, #040405 100%);
  box-shadow: inset 0 calc(var(--L) * .16) calc(var(--L) * .12) calc(var(--L) * -.05) rgba(0, 0, 0, .75);
  transition: box-shadow .25s;
}
/* The lit lens fades in over the dark one. */
.tl-lens::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%; opacity: 0; transition: opacity .22s;
  background:
    repeating-radial-gradient(circle at 50% 50%, rgba(255, 255, 255, .13) 0 1.1%, transparent 1.1% 4.6%),
    radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--lens) 25%, #fff) 0, color-mix(in srgb, var(--lens) 55%, #fff) 14%, color-mix(in srgb, var(--lens) 88%, #fff) 34%, var(--lens) 60%, color-mix(in srgb, var(--lens) 76%, #000) 100%);
}
/* Glass: a soft highlight top-left and a thin bright rim (Fresnel edge). */
.tl-lens::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(ellipse 42% 26% at 36% 24%, rgba(255, 255, 255, .26), transparent 72%);
  box-shadow: inset 0 0 0 calc(var(--L) * .012) rgba(255, 255, 255, .1), inset 0 calc(var(--L) * -.05) calc(var(--L) * .08) rgba(255, 255, 255, .05);
}
.tl-lamp.is-on .tl-lens {
  box-shadow:
    inset 0 calc(var(--L) * .15) calc(var(--L) * .12) calc(var(--L) * -.07) rgba(0, 0, 0, .45),
    0 0 calc(var(--L) * .16) calc(var(--L) * .03) color-mix(in srgb, var(--lens) 90%, transparent),
    0 0 calc(var(--L) * .55) calc(var(--L) * .12) color-mix(in srgb, var(--lens) 45%, transparent);
}
.tl-lamp.is-on .tl-lens::before { opacity: 1; }
.tl-lamp.is-on .tl-lens::after { background: radial-gradient(ellipse 42% 26% at 36% 24%, rgba(255, 255, 255, .5), transparent 72%); }

/* Visor (hood): a crescent over the top of the lens, thick at the top and
   tapering down the sides, lit from inside when its lens is on. */
.tl-visor {
  position: absolute; left: -12%; right: -12%; top: -14%; height: 74%; pointer-events: none;
  border-style: solid; border-color: #3b4149 #24282d transparent;
  border-width: calc(var(--L) * .1) calc(var(--L) * .025) 0;
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  filter: drop-shadow(0 calc(var(--L) * .035) calc(var(--L) * .025) rgba(0, 0, 0, .6));
  transition: border-color .25s;
}
.tl-lamp.is-on .tl-visor { border-top-color: color-mix(in srgb, var(--lens) 24%, #3b4149); border-left-color: color-mix(in srgb, var(--lens) 18%, #24282d); border-right-color: color-mix(in srgb, var(--lens) 18%, #24282d); }
.tl[data-orient="horizontal"] .tl-visor { top: -15%; }

.tl-lamp:hover:not(.is-on) .tl-lens { box-shadow: inset 0 calc(var(--L) * .16) calc(var(--L) * .12) calc(var(--L) * -.05) rgba(0, 0, 0, .75), 0 0 calc(var(--L) * .12) color-mix(in srgb, var(--lens) 35%, transparent); }
.tl-lamp:active .tl-lens { transform: scale(.985); }

/* ---- labels ---- */
.tl-labels {
  display: grid; grid-template-rows: repeat(3, calc(var(--L) * 1.24)); align-items: center;
  padding-block: calc(var(--L) * .17); max-width: calc(var(--L) * 3.1);
}
.tl[data-orient="horizontal"] .tl-labels {
  grid-template-rows: auto; grid-template-columns: repeat(3, calc(var(--L) * 1.24));
  padding-block: 0; padding-inline: calc(var(--L) * .17); max-width: none; align-items: start;
}
.tl.no-labels .tl-labels { display: none; }
.tl-label {
  --lens: #ff3b30;
  display: flex; align-items: center; gap: .45em; padding: .2em .35em; margin: 0; border: 0; border-radius: .35em;
  background: none; color: var(--stage-ink); text-align: left; cursor: pointer;
  font: 650 clamp(13px, calc(var(--L) * .25), 120px)/1.12 var(--font-display); letter-spacing: -.01em;
  opacity: .32; transition: opacity .25s, transform .25s;
  overflow-wrap: anywhere;
}
.tl-label[data-c="amber"] { --lens: #f0a000; }
.tl-label[data-c="green"] { --lens: #10b871; }
.tl-label:hover { opacity: .6; }
.tl-label.is-on { opacity: 1; transform: translateX(calc(var(--L) * .04)); }
.tl[data-orient="horizontal"] .tl-label { flex-direction: column; text-align: center; font-size: clamp(12px, calc(var(--L) * .19), 96px); gap: .3em; }
.tl[data-orient="horizontal"] .tl-label.is-on { transform: translateY(calc(var(--L) * .03)); }
.tl-dot { flex: none; width: .55em; height: .55em; border-radius: 50%; background: var(--lens); transition: box-shadow .25s; }
.tl-label.is-on .tl-dot { box-shadow: 0 0 0 .16em color-mix(in srgb, var(--lens) 28%, transparent), 0 0 .7em var(--lens); }
.tl-label.tl-in span { animation: tl-in .35s ease-out; }
@keyframes tl-in { from { opacity: 0; transform: translateX(-.4em); } }

/* Tall, narrow space (a slim Board widget): only the lit label, under the light. */
@container (max-aspect-ratio: 4/5) {
  .tl:not(.no-labels)[data-orient="vertical"] { --L: calc(min(17.5cqh, 50cqw) * var(--k)); }
  .tl[data-orient="vertical"] .tl-scene { flex-direction: column; align-items: center; gap: calc(var(--L) * .22); }
  .tl[data-orient="vertical"] .tl-labels { display: block; padding: 0; max-width: 92cqw; }
  .tl.no-labels .tl-labels { display: none; }
  .tl[data-orient="vertical"] .tl-label { display: none; justify-content: center; text-align: center; font-size: clamp(13px, calc(var(--L) * .3), 90px); }
  .tl[data-orient="vertical"] .tl-label.is-on { display: flex; transform: none; text-wrap: balance; }
  .tl[data-orient="vertical"] .tl-label .tl-dot { display: none; }
}

/* ---- countdown and hint ---- */
.tl-next {
  position: absolute; top: clamp(8px, 2.4cqmin, 26px); left: 50%; transform: translateX(-50%);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.tl-hint {
  position: absolute; left: 0; right: 0; bottom: clamp(6px, 2cqmin, 20px); text-align: center; pointer-events: none;
  font-size: clamp(11px, 2.4cqmin, 20px); color: color-mix(in srgb, var(--stage-ink) 50%, transparent);
  transition: opacity .4s;
}
.tl-hint.is-gone { opacity: 0; }
@container (max-height: 300px) { .tl-hint { display: none; } }

/* ---- settings ---- */
.tl-word { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.tl-word:last-child { margin-bottom: 0; }
.tl-word .tl-dot { width: 14px; height: 14px; --lens: #ff3b30; }
.tl-word[data-c="amber"] .tl-dot { --lens: #ffb11a; }
.tl-word[data-c="green"] .tl-dot { --lens: #17df8a; }
.tl-mins .set-group:last-child { border-bottom: 1px solid var(--line-soft); }
