/* Mango Live Check: the broadcast box.

   This file is only the box, the one thing that goes out. It is authored at
   real pixels, 1080 by 1200, so a size written here is the size a viewer
   sees relative to the frame, and the 36 pixel minimum can be checked by
   reading this file. The page may show the box smaller to fit a laptop
   screen; that is a uniform scale of the whole frame and changes no
   proportion. The presenter's page around it lives in desk.css.

   Nothing animates. Screens change instantly. */

:root {
  /* The box. Every colour that can reach the broadcast is in this list and
     nowhere else. Problems and solutions each have exactly one colour, so
     a viewer learns within one screen that orange-red is what is wrong and
     gold is what to do about it. There is no separate "fail red". */
  --stage:    #2A1617;
  --glow:     rgba(179, 44, 26, 0.25);   /* #B32C1A at a quarter, top corner */
  --tile:     #331C1D;
  --text:     #FFF3EA;
  --muted:    #D4B2A7;                   /* also every passed check */
  --divider:  #4A2A27;
  --problem:  #FF582D;
  --solution: #FFC371;

  /* Older names, kept pointing at the new colours so no rule is orphaned. */
  --fail:   var(--problem);
  --accent: var(--solution);

  /* Type. Archivo at its narrowest and heaviest for everything that is a
     number or a headline; a geometric sans for the sentences under them.
     Both are the Mango Studio site's own. */
  --display: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --body:    'Plus Jakarta Sans', 'Helvetica Neue', Arial, sans-serif;

  /* Overwritten from box.js so the box size has one home. */
  --box-w: 1080px;
  --box-h: 1200px;

  --gutter: 64px;
  --fit: 1;    /* set per screen when a screen would otherwise overflow */
}

/* ============================================================== the box ==
   From here down, every size is a real broadcast pixel. */

/* The edge the presenter sees is drawn by the frame in desk.css, outside
   the box, so capturing the box exactly never catches it. */
.box {
  position: relative;
  width: var(--box-w);
  height: var(--box-h);
  /* One soft glow and nothing else. Stream encoders turn gentle gradients
     into visible bands, so this is the only one behind the content, and it
     is large and low-contrast enough to survive compression. No grain. */
  background:
    radial-gradient(ellipse 900px 760px at 100% 0%, var(--glow) 0%, rgba(179, 44, 26, 0) 100%),
    var(--stage);
  color: var(--text);
  font-family: var(--body);
  overflow: hidden;
}

/* Every screen fills the box and never scrolls.
   The inner box is laid out larger than the screen by exactly 1/--fit and
   then scaled back down by --fit, so a screen with more words than usual
   shrinks as a whole instead of scrolling. The floor is 0.9 and the smallest
   size in this file is 40 pixels, which puts the smallest text that can ever
   reach the broadcast at 36 pixels: the minimum in the brief, exactly. */
.screen {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.screen[hidden] { display: none; }

.screen-inner {
  position: absolute;
  top: 0;
  left: 0;
  width: calc(100% / var(--fit));
  height: calc(100% / var(--fit));
  padding: 48px var(--gutter) 64px;
  display: flex;
  flex-direction: column;
  /* Plain centring lets an over-tall column overflow upward as well as
     down, which puts a headline off the top of the box. */
  justify-content: safe center;
  transform: scale(var(--fit));
  transform-origin: top left;
}

/* A headline does the job the small grey labels used to do. */
.screen-head {
  margin: 0 0 32px;
  font-size: 64px;
  line-height: 1.1;
  font-weight: 800;
  font-stretch: 78%;
  letter-spacing: -0.5px;
}

.caption {
  margin: 0 0 24px;
  font-size: 40px;
  color: var(--muted);
  font-weight: 500;
}

.source {
  margin: 32px 0 0;
  font-size: 40px;
  color: var(--muted);
  font-weight: 400;
}

/* --------------------------------------------------------------- running */

.running-host {
  margin: 0 0 40px;
  font-size: 48px;
  font-weight: 700;
  color: var(--muted);
  overflow-wrap: anywhere;
}

.steps {
  list-style: none;
  margin: 0;
  padding: 0;
}

.steps li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 32px;
  padding: 18px 0;
  border-bottom: 1px solid var(--divider);
  font-size: 44px;
  font-weight: 600;
  color: var(--muted);
}

.steps li[data-state="running"] { color: var(--text); }
.steps li[data-state="done"] { color: var(--text); }
.steps li[data-state="skipped"],
.steps li[data-state="failed"] { color: var(--muted); }

.step-state {
  font-size: 40px;
  font-weight: 500;
  color: var(--muted);
  white-space: nowrap;
}

.steps li[data-state="done"] .step-state { color: var(--accent); }

/* ------------------------------------------------------------ 1. score */

.screen-score { justify-content: center; }

.biz-name {
  margin: 0;
  font-size: 64px;
  line-height: 1.08;
  font-weight: 800;
  font-stretch: 78%;
  overflow-wrap: anywhere;
}

.biz-meta {
  margin: 8px 0 0;
  font-size: 44px;
  font-weight: 500;
  color: var(--muted);
}

.score-row {
  margin: 8px 0 0;
  display: flex;
  align-items: baseline;
  gap: 28px;
}

/* Section 7. The numeral is brand orange at every score. A green number
   tells an invisible business it is fine, which is the one thing the screen
   must never say. The bad news is carried by the status line underneath. */
.score-digit {
  font-size: 420px;
  line-height: 0.82;
  font-weight: 900;
  font-stretch: 62%;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.score-of {
  font-size: 56px;
  font-weight: 600;
  color: var(--muted);
}

.headline {
  margin: 24px 0 0;
  font-size: 60px;
  line-height: 1.16;
  font-weight: 700;
  font-stretch: 88%;
}

.statusline {
  margin: 20px 0 0;
  font-size: 48px;
  font-weight: 700;
  color: var(--fail);
}

/* ------------------------------------ 2. the answer they are missing from */

.ranking {
  list-style: none;
  margin: 0;
  padding: 0;
}

.ranking li {
  display: flex;
  align-items: baseline;
  gap: 32px;
  padding: 20px 0;
  border-bottom: 1px solid var(--divider);
  font-size: 52px;
  font-weight: 700;
  font-stretch: 85%;
}

.ranking li:last-child { border-bottom: 0; }

.rank-num {
  flex: 0 0 72px;
  font-size: 52px;
  font-weight: 800;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.rank-name { overflow-wrap: anywhere; }

/* The business itself, dimmed, at the bottom of the list it is missing from. */
.ranking li.is-them { color: var(--muted); }
.ranking li.is-them .rank-num { color: var(--muted); }

.rank-tag {
  margin-left: auto;
  font-size: 44px;
  font-weight: 700;
  color: var(--fail);
  white-space: nowrap;
}

/* ------------------------------------------------ 3. what AI says they do */

.quote {
  margin: 0;
  padding: 0 0 0 32px;
  border-left: 8px solid var(--accent);
  font-size: 48px;
  line-height: 1.3;
  font-weight: 500;
}

/* -------------------------------------------- 4. what is broken right now */

.findings {
  list-style: none;
  margin: 0;
  padding: 0;
}

.findings li {
  display: flex;
  align-items: baseline;
  gap: 32px;
  padding: 18px 0;
  border-bottom: 1px solid var(--divider);
}

.findings li:last-child { border-bottom: 0; }

/* The number is what the eye lands on while the sentence is read aloud, so
   every number starts on the same left edge and every sentence starts on the
   same one after it. A long value such as "1.6 seconds" steps down a size
   rather than pushing its own sentence out of the column. */
.f-value {
  flex: 0 0 300px;
  font-size: 76px;
  line-height: 1;
  font-weight: 900;
  font-stretch: 70%;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.f-value[data-long="true"] { font-size: 56px; }

.f-text {
  margin: 0;
  font-size: 42px;
  line-height: 1.22;
  font-weight: 500;
}

/* ---------------------------------------------------- 5. the five checks */

.checks {
  list-style: none;
  margin: 0;
  padding: 0;
}

.checks li {
  display: flex;
  align-items: baseline;
  gap: 28px;
  padding: 20px 0;
  border-bottom: 1px solid var(--divider);
}

.checks li:last-child { border-bottom: 0; }

/* A pass is quiet. Only a failure draws the eye, because a failure is the
   reason the owner picks up the phone. Passes are never celebrated. */
.checks li[data-pass="true"] {
  color: var(--muted);
  font-size: 48px;
  font-weight: 600;
}

.checks li[data-pass="false"] {
  color: var(--text);
  font-size: 60px;
  font-weight: 800;
  font-stretch: 85%;
}

.c-mark {
  flex: 0 0 56px;
  font-weight: 800;
}

.checks li[data-pass="false"] .c-mark { color: var(--fail); }

/* Not checked is quieter still. It is not a failure and must never read like
   one: no problem colour, no weight, and the words say so outright. */
.checks li[data-pass="none"] {
  color: var(--muted);
  font-size: 48px;
  font-weight: 600;
}

.c-note {
  margin-left: auto;
  font-size: 40px;
  font-weight: 500;
  font-stretch: 100%;
  letter-spacing: 0.02em;
  color: var(--muted);
  white-space: nowrap;
}

.c-label { overflow-wrap: anywhere; }

/* --------------------------------------------------------- 6. three fixes */

.fixes {
  list-style: none;
  margin: 0;
  padding: 0;
}

.fixes li {
  display: flex;
  gap: 32px;
  padding: 20px 0;
  border-bottom: 1px solid var(--divider);
}

.fixes li:last-child { border-bottom: 0; }

.x-num {
  flex: 0 0 90px;
  font-size: 84px;
  line-height: 0.92;
  font-weight: 900;
  font-stretch: 62%;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.x-title {
  margin: 0 0 6px;
  font-size: 52px;
  line-height: 1.1;
  font-weight: 800;
  font-stretch: 82%;
}

.x-body {
  margin: 0;
  font-size: 40px;
  line-height: 1.22;
  font-weight: 500;
  color: var(--muted);
}

/* -------------------------------------------------------- 7. report card */

/* The one screen where a dashboard style is right, because it is looked at
   whole and screenshotted rather than narrated line by line. */
.screen-card { justify-content: center; }

/* Score down the whole left column, the other three stacked on the right.
   Stated explicitly rather than left to auto-placement, which puts the
   fourth tile on a row of its own underneath everything. */
.card-grid {
  display: grid;
  min-height: 0;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto auto;
  gap: 24px;
  /* Sized by its own content and centred, rather than stretched to the full
     height of the box. Filling the box leaves a third of the score tile
     empty, which reads as a layout fault rather than as breathing room. */
  max-height: 100%;
}

.tile-score   { grid-column: 1; grid-row: 1 / -1; }
.tile-models  { grid-column: 2; grid-row: 1; }
.tile-problem { grid-column: 2; grid-row: 2; }
.tile-next    { grid-column: 2; grid-row: 3; }

.tile {
  background: var(--tile);
  border: 1px solid var(--divider);
  border-radius: 28px;
  padding: 32px 36px;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.tile-label {
  margin: 0 0 12px;
  font-size: 40px;
  font-weight: 600;
  color: var(--muted);
}

.tile-score-row {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 20px;
}

.tile-digit {
  font-size: 250px;
  line-height: 0.84;
  font-weight: 900;
  font-stretch: 62%;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.tile-of {
  font-size: 44px;
  font-weight: 600;
  color: var(--muted);
}

.tile-name {
  margin: auto 0 0;
  font-size: 48px;
  line-height: 1.08;
  font-weight: 800;
  font-stretch: 78%;
  overflow-wrap: anywhere;
}

.model-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}

.model-rows li {
  display: flex;
  align-items: baseline;
  gap: 20px;
  padding: 10px 0;
  font-size: 44px;
  font-weight: 700;
}

.m-mark { font-weight: 900; }
.model-rows li[data-listed="true"] .m-mark { color: var(--accent); }
.model-rows li[data-listed="false"] .m-mark { color: var(--fail); }
.model-rows li[data-listed="null"] { color: var(--muted); }

.tile-number {
  margin: 0;
  font-size: 84px;
  line-height: 1;
  font-weight: 900;
  font-stretch: 66%;
  font-variant-numeric: tabular-nums;
}

.tile-sentence {
  margin: 12px 0 0;
  font-size: 40px;
  line-height: 1.2;
  font-weight: 500;
  color: var(--muted);
}

.tile-cta {
  margin: auto 0 0;
  font-size: 48px;
  line-height: 1.1;
  font-weight: 800;
  font-stretch: 82%;
  color: var(--accent);
}

/* ------------------------------------------------------------ calm state */

.calm-kicker {
  margin: 0 0 20px;
  font-size: 44px;
  font-weight: 600;
  color: var(--muted);
}

.calm-text {
  margin: 0;
  font-size: 64px;
  line-height: 1.14;
  font-weight: 700;
  font-stretch: 85%;
}

/* ----------------------------------------------------------- the marks */

/* Which screen is showing. Small, quiet, at the foot of the box. */
.marks {
  position: absolute;
  left: var(--gutter);
  bottom: 24px;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 14px;
}

.marks li {
  width: 44px;
  height: 8px;
  background: var(--divider);
  border-radius: 4px;
}

.marks li[data-on="true"] { background: var(--accent); }

/* ============================================= restyle: type and colour ==
   Kept together at the end so the whole broadcast palette can be read in
   one place. Sizes are untouched: everything above still decides them. */

/* Headlines, the score, every number and every fix title: Archivo at its
   narrowest width and heaviest weight, set tight like a poster. */
.screen-head,
.biz-name,
.headline,
.score-digit,
.tile-digit,
.f-value,
.rank-num,
.x-num,
.x-title,
.tile-number,
.calm-kicker,
.running-host {
  font-family: var(--display);
  font-weight: 900;
  font-stretch: 62%;
  letter-spacing: -0.01em;
}

.screen-head, .biz-name, .headline { line-height: 1.04; }

/* Sentences are the body face. */
.caption, .biz-meta, .quote, .f-text, .x-body, .c-label, .rank-name,
.tile-sentence, .tile-name, .tile-cta, .calm-text, .steps, .source,
.score-of, .tile-of, .tile-label, .model-rows, .c-note, .rank-tag, .statusline {
  font-family: var(--body);
  font-stretch: 100%;
}

/* The score is the one place a gradient is allowed inside the box: gold at
   the top running into the problem colour at the foot. */
.score-digit,
.tile-digit {
  background: linear-gradient(180deg, var(--solution) 0%, var(--problem) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  /* Clipped gradients lose the bottom of a tight line box. */
  padding-bottom: 0.04em;
}

/* Problems. */
.f-value,
.tile-number,
.rank-tag,
.statusline,
.checks li[data-pass="false"],
.checks li[data-pass="false"] .c-mark,
.model-rows li[data-listed="false"] .m-mark { color: var(--problem); }

/* Solutions. */
.x-num,
.x-title,
.tile-cta,
.model-rows li[data-listed="true"] .m-mark { color: var(--solution); }

/* Everything that passed, and everything that was not checked, recedes. */
.checks li[data-pass="true"],
.checks li[data-pass="none"],
.model-rows li[data-listed="null"] { color: var(--muted); }

/* A quote is neither a problem nor a fix, so its rule is the divider. */
.quote { border-left-color: var(--divider); }

.steps li[data-state="done"] .step-state { color: var(--text); }

.tile { background: var(--tile); border-color: var(--divider); }

/* No model was asked: the models tile is left out entirely and the biggest
   problem takes its rows. */
.card-grid.no-models .tile-models { display: none; }
.card-grid.no-models .tile-problem { grid-row: 1 / 3; }

/* The card's problem number and next step carry the poster weight too. */
.tile-number { font-size: 140px; line-height: 0.9; margin: 4px 0 8px; }
.tile-cta {
  font-family: var(--display);
  font-weight: 900;
  font-stretch: 62%;
  font-size: 68px;
  line-height: 1;
}

.tile-name { font-family: var(--display); font-weight: 900; font-stretch: 62%; font-size: 64px; line-height: 1; }

