/* ==========================================================================
   Terminal Frame: a terminal window around a product's ASCII mascot.
   Markup: terminalFrame.php. Behaviour: terminalFrame.js (OS pick, one-shot print).
   Colour comes from --kb-product-color (set per product on <html>).
   ========================================================================== */

.tf {
  --tf-accent: var(--kb-product-color, #38bdf8);
  --tf-line: var(--color-border-strong, rgba(255, 255, 255, 0.2));
  --tf-ink: #e2e8f0;
  --tf-dim: var(--muted, #94a3b8);

  /* Title-bar skin: Linux by default (also what no-JS shows); mac and win override these. */
  --tf-controls-col: 3;
  --tf-controls-justify: end;
  --tf-title-col: 2;
  --tf-title-align: center;
  --tf-c-w: 1.15rem;
  --tf-c-h: 1.15rem;
  --tf-c-gap: 0.3rem;
  --tf-c-edge: rgba(255, 255, 255, 0.18);
  --tf-glyph: 1;
  --tf-order-min: 1;
  --tf-order-max: 2;
  --tf-order-close: 3;
  --tf-bar-pad: 0.6rem;
  --tf-dot-min: transparent;
  --tf-dot-max: transparent;
  --tf-dot-close: transparent;

  position: relative;
  width: min(100%, 26rem);
  background: #05080c;
  border: 1px solid var(--tf-line);
  border-radius: 0;
  /* No outer glow: the edge is lit only by the one-shot pass below. */
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Consolas, monospace);
}

:is(.tf[data-chrome="mac"], html[data-os="mac"] .tf:not([data-chrome])) {
  --tf-controls-col: 1;
  --tf-controls-justify: start;
  --tf-c-w: 0.55rem;
  --tf-c-h: 0.55rem;
  --tf-c-gap: 0.35rem;
  --tf-c-edge: transparent;
  --tf-glyph: 0;
  --tf-order-close: 1;
  --tf-order-min: 2;
  --tf-order-max: 3;
  --tf-dot-close: #b9534f;
  --tf-dot-min: #b98a2f;
  --tf-dot-max: #3f9a57;
}

:is(.tf[data-chrome="win"], html[data-os="win"] .tf:not([data-chrome])) {
  --tf-title-col: 1 / 3;
  --tf-title-align: start;
  --tf-c-w: 2.6rem;
  --tf-c-h: 2rem;
  --tf-c-gap: 0;
  --tf-c-edge: transparent;
  --tf-bar-pad: 0;
}

/* ── Title bar ───────────────────────────────────────────────────────────── */

.tf-bar {
  display: grid;
  grid-template-columns: 1fr minmax(0, auto) 1fr;
  column-gap: 0.75rem;
  align-items: center;
  min-height: 2rem;
  padding-inline: var(--tf-bar-pad);
  border-bottom: 1px solid var(--color-border-muted, rgba(255, 255, 255, 0.12));
  background: rgba(255, 255, 255, 0.035);
  color: var(--tf-dim);
  user-select: none;
}

:is(.tf[data-chrome="win"], html[data-os="win"] .tf:not([data-chrome])) .tf-bar {
  padding-inline-start: 0.75rem;
}

.tf-title {
  grid-row: 1;
  grid-column: var(--tf-title-col);
  min-width: 0;
  overflow: hidden;
  text-align: var(--tf-title-align);
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.72rem;
  letter-spacing: 0.02em;
}

.tf-controls {
  grid-row: 1;
  grid-column: var(--tf-controls-col);
  justify-self: var(--tf-controls-justify);
  align-self: stretch;
  display: flex;
  align-items: center;
  gap: var(--tf-c-gap);
}

/* Look like window buttons but are not: no pointer, no hover, hidden from assistive tech. */
.tf-c {
  position: relative;
  display: block;
  width: var(--tf-c-w);
  height: var(--tf-c-h);
  border: 1px solid var(--tf-c-edge);
  color: var(--tf-dim);
}
.tf-c--min { order: var(--tf-order-min); background: var(--tf-dot-min); }
.tf-c--max { order: var(--tf-order-max); background: var(--tf-dot-max); }
.tf-c--close { order: var(--tf-order-close); background: var(--tf-dot-close); }

.tf-c::before,
.tf-c::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  background: currentColor;
  opacity: var(--tf-glyph);
}
.tf-c--min::before { width: 0.5rem; height: 1px; transform: translate(-50%, 0.18rem); }
.tf-c--min::after { display: none; }
.tf-c--max::before { width: 0.45rem; height: 0.45rem; background: none; border: 1px solid currentColor; transform: translate(-50%, -50%); }
.tf-c--max::after { display: none; }
.tf-c--close::before,
.tf-c--close::after { width: 0.62rem; height: 1px; }
.tf-c--close::before { transform: translate(-50%, -50%) rotate(45deg); }
.tf-c--close::after { transform: translate(-50%, -50%) rotate(-45deg); }

/* ── Screen: a short session ─────────────────────────────────────────────── */

.tf-screen {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 0.85rem 1rem 1rem;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--tf-ink);
}

.tf-line { margin: 0; overflow-wrap: anywhere; }
.tf-ps1 { color: var(--tf-accent); font-weight: 700; }

.tf-art {
  display: block;
  width: 100%;
  height: auto;
  max-height: clamp(11rem, 38vh, 21rem);
  margin-inline: auto;
  object-fit: contain;
  /* Phosphor, not neon: a tight halo that follows the glyphs. */
  filter: drop-shadow(0 0 3px color-mix(in srgb, var(--tf-accent) 45%, transparent));
}

/* Reset in full: page stylesheets style bare dl/div/dt (rules, padding, bold). */
.tf-facts { display: grid; margin: 0; padding: 0; }
.tf-facts > div { display: grid; grid-template-columns: 9ch minmax(0, 1fr); gap: 1ch; margin: 0; padding: 0; border: 0; background: none; }
.tf-facts dt { margin: 0; padding: 0; font-weight: 400; color: var(--tf-dim); }
.tf-facts dd { margin: 0; padding: 0; color: var(--tf-ink); }

.tf-cursor {
  display: inline-block;
  width: 0.6em;
  height: 1.05em;
  vertical-align: text-bottom;
  background: var(--tf-accent);
  animation: tf-blink 1.1s steps(1) infinite;
}
@keyframes tf-blink { 50% { opacity: 0; } }

/* ── One-shot print, played when the frame scrolls into view (terminalFrame.js) ── */

.tf.is-armed:not(.is-live) .tf-art { clip-path: inset(0 0 100% 0); }
.tf.is-armed:not(.is-live) :is(.tf-facts > div, .tf-prompt) { opacity: 0; }

.tf-facts > div:nth-child(2) { --i: 1; }
.tf-facts > div:nth-child(3) { --i: 2; }
.tf-facts > div:nth-child(4) { --i: 3; }
.tf-facts > div:nth-child(5) { --i: 4; }

@media (prefers-reduced-motion: no-preference) {
  .tf.is-live {
    --tf-print: calc(var(--tf-rows, 16) * 38ms);
    --tf-after-art: calc(140ms + var(--tf-print));
  }
  /* The mascot prints row by row, like output arriving, not a fade. */
  .tf.is-live .tf-art { animation: tf-print var(--tf-print) steps(var(--tf-rows, 16), end) 140ms both; }
  .tf.is-live .tf-facts > div { animation: tf-appear 0.01s linear calc(var(--tf-after-art) + var(--i, 0) * 90ms) both; }
  .tf.is-live .tf-prompt { animation: tf-appear 0.01s linear calc(var(--tf-after-art) + 420ms) both; }

  /* The lit edge: one pass of light along the top rule, after the PowerLocal footer's
     ruled flow. One gradient revealed by a travelling window, plus a soft bloom under it. */
  .tf-flow {
    position: absolute;
    inset: -1px -1px auto;
    height: 2.5rem;
    overflow: hidden;
    pointer-events: none;
    z-index: 2;
  }
  .tf-flow::before,
  .tf-flow::after {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    background: linear-gradient(90deg, var(--tf-accent), #fff 50%, var(--tf-accent));
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 35%, #000 65%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 35%, #000 65%, transparent);
    -webkit-mask-size: 42% 100%;
    mask-size: 42% 100%;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: -80% 0;
    mask-position: -80% 0;
    opacity: 0;
  }
  .tf-flow::before { height: 1px; }
  .tf-flow::after { height: 12px; filter: blur(7px); --tf-peak: 0.45; }
  .tf.is-live .tf-flow::before,
  .tf.is-live .tf-flow::after { animation: tf-flow 1.3s linear 1 both; }
}

@media (prefers-reduced-motion: reduce) {
  .tf-flow { display: none; }
  .tf-cursor { animation: none; }
}

@keyframes tf-print { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes tf-appear { from { opacity: 0; } to { opacity: 1; } }
@keyframes tf-flow {
  0% { -webkit-mask-position: -80% 0; mask-position: -80% 0; opacity: 0; }
  14%, 86% { opacity: var(--tf-peak, 1); }
  100% { -webkit-mask-position: 180% 0; mask-position: 180% 0; opacity: 0; }
}
