/*! Apollo Robot Advisor - hallmark:apollo-advisor-v1 */

/* Brand tokens, locked before any markup.
 * Pulled from apolloofficesystems.com computed styles, 2026-09-18:
 *   red   rgb(254,0,0)   ink rgb(51,51,51)   ground white / rgb(250,250,250)
 *   Roboto body (316 uses), Raleway headings (92 uses)
 *
 * ⛔ CONTRAST, measured not assumed: white on #FE0000 is 4.03:1 and #333 on
 * #FE0000 is 3.14:1. Both FAIL WCAG AA for normal text (4.5:1). The red is
 * therefore allowed on LARGE text only, and never as a body-text ground. Their
 * live site runs white nav text on full-width red bands; we do not copy that.
 *
 * ⛔ The ground is a cool off-white, NOT cream/sand/beige/warm paper. That band
 * (L>0.88, C 0.015-0.06, H 60-100) is the top AI tell and it is banned on every
 * brief, not just premium ones.
 */
/* ⭐ Sampled from the LOGO FILE itself (public/img/apollo-logo.png), not from
 * the site's CSS. The logo is TWO colours and nothing else, counting pixels
 * whose palette alpha is above 128, of which there are 3,658:
 *     #000000  40.2%
 *     #FE0000  12.3%, plus ~14% more that is antialiasing of the same red
 *       (#FF0000 7.2%, #F80101 3.3%, #FC0000 3.1%)
 * ⚠️ This census used to read 45.3% and 14.3% with no method given. Decoding
 * the PNG directly reproduces 32.4/10.0 at alpha>0, 40.2/12.3 at alpha>128 and
 * 52.8/16.7 at alpha==255, and none of those is 45.3, so the old pair could not
 * be reproduced and the threshold is now stated with the number. The CONCLUSION
 * is unchanged at every threshold: black dominates, red is second, and nothing
 * else is brand. kimi_k3 surfaced the inconsistency 2026-09-18.
 * That is the entire brand system: black, red, white. An earlier draft of this
 * file invented a slate #1f3448 as a "second tone". It is not Apollo's colour
 * and it is gone. Black is the logo's own second colour and does that job.
 */
:root {
  --ground:      oklch(0.985 0.002 250);   /* cool off-white, chroma 0.002 */
  --panel:       #fafafa;                   /* theirs */
  --black:       #000000;                   /* logo */
  --ink:         #333333;                   /* their body text, easier than pure black at 17px */
  --ink-soft:    #5c5c5c;
  --hair:        #e3e4e6;
  --action:      #fe0000;                   /* logo, ~2% of any viewport */
  --action-deep: #c40000;                   /* hover/active only, not a ground */
  --slate:       var(--black);              /* alias kept so no rule silently loses its colour */
  --radius:      6px;
  --maxw:        1120px;
  --font-head:   Raleway, "Helvetica Neue", Arial, sans-serif;
  --font-body:   Roboto, -apple-system, "Segoe UI", Arial, sans-serif;
  --mono:        ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font: 400 17px/1.55 var(--font-body);
  overflow-x: hidden;
}
h1, h2, h3 { font-family: var(--font-head); margin: 0 0 .5em; }

/* Scale carries hierarchy, weight does not.
 * Target h1:lede is 5:1 desktop, 2.5:1 at 390px. Measured in the browser with
 * getComputedStyle, never inferred from the clamp. */
/* Solved for the two targets rather than guessed, then measured in the browser:
 *   slope (96px - 45.6px) / (1440 - 390) = 4.95vw, base 1.54rem
 *   1440px -> 96px / 18px = 5.33  (target 5.0)
 *    390px -> 45.6px / 18px = 2.53 (target 2.5)
 * The previous clamp (1.5rem + 3.9vw) measured 4.2:1 at 1440, which misses. */
h1 {
  font-size: clamp(2.85rem, 1.54rem + 4.95vw, 6.5rem);
  font-weight: 700; letter-spacing: -.025em; line-height: .98;
  /* Pure black, matching the logo. #333 is their BODY colour; at display size
     next to a #000 logo the softer charcoal reads as a near-miss. */
  color: var(--black);
}
.lede { font-size: 18px; color: var(--ink-soft); max-width: 62ch; }
h2 { font-size: clamp(1.4rem, 1.1rem + 1vw, 2rem); font-weight: 700; }
h3 { font-size: 1.05rem; font-weight: 700; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }
.eyebrow {
  font: 500 12px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-soft); margin: 0 0 14px;
}
/* Red at LARGE sizes only on white (4.03:1 = AA Large, fails AA normal).
   The h1 is 45.6px on phone and 96px on desktop, so this is safely large. */
.accent { color: var(--action); }

/* ---- Header. The phone stays reachable throughout. ---- */
.hdr {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 18px 24px; max-width: var(--maxw); margin: 0 auto;
  border-bottom: 1px solid var(--hair);
}
.hdr__brand { display: inline-flex; align-items: center; min-height: 44px; }
.hdr__brand img { display: block; width: 100px; height: auto; }
.hdr__tel {
  /* 44px minimum: measured at 39px and the clipped-content audit counts that a
     failure. Flex so the label centres once min-height drives the box. */
  display: inline-flex; align-items: center; min-height: 44px;
  font: 600 15px/1 var(--font-body); color: var(--ink); text-decoration: none;
  border: 1.5px solid var(--ink); border-radius: var(--radius); padding: 0 16px;
  white-space: nowrap;
}
.hdr__tel:hover { background: var(--ink); color: #fff; }

/* ---- Hero. The advisor starts here: traffic arrives from their own
       homepage already intending to use it. ---- */
.hero { padding: 40px 0 8px; }
.hero h1 { max-width: 16ch; }

/* ---- The advisor card ---- */
.card {
  background: #fff; border: 1px solid var(--hair); border-radius: 10px;
  padding: 28px; margin: 28px 0 40px;
  box-shadow: 0 1px 2px rgba(31,52,72,.05);
}
.rail { height: 3px; background: var(--hair); border-radius: 2px; overflow: hidden; }
/* scaleX, not width: animating width relayouts the card on every step. */
.rail__fill {
  height: 100%; width: 100%; background: var(--action);
  transform: scaleX(0); transform-origin: left center;
  transition: transform .25s ease;
}
.step { font: 500 12px/1 var(--mono); color: var(--action); margin: 14px 0 6px; }
.q { font-size: clamp(1.25rem, 1rem + 1vw, 1.7rem); font-weight: 700;
     font-family: var(--font-head); margin: 0 0 18px; }

/* Options are radio pills at 56px, never a <select> for a short list. */
.opts { display: grid; gap: 10px; }
.opt {
  display: flex; align-items: center; gap: 12px; min-height: 56px;
  padding: 12px 16px; border: 1.5px solid var(--hair); border-radius: var(--radius);
  background: #fff; cursor: pointer; font: 400 16px/1.35 var(--font-body);
  text-align: left; width: 100%;
}
.opt:hover { border-color: var(--slate); }
.opt[aria-pressed="true"] { border-color: var(--action); box-shadow: inset 0 0 0 1px var(--action); }
.opt__dot {
  flex: none; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--hair); background: #fff;
}
.opt[aria-pressed="true"] .opt__dot { border-color: var(--action); background: var(--action); }

.fields { display: grid; gap: 14px; grid-template-columns: 1fr 1fr; }
.fields label { display: block; font: 500 13px/1.3 var(--font-body); color: var(--ink-soft); margin-bottom: 5px; }
.fields input {
  width: 100%; min-height: 48px; padding: 10px 12px; font: 400 16px var(--font-body);
  border: 1.5px solid var(--hair); border-radius: var(--radius); background: #fff; color: var(--ink);
}
.fields input:focus-visible { outline: 2px solid var(--slate); outline-offset: 1px; }
.fields .full { grid-column: 1 / -1; }

.nav { display: flex; gap: 12px; align-items: center; margin-top: 22px; }
.btn {
  min-height: 52px; padding: 14px 22px; border-radius: var(--radius); border: 1.5px solid transparent;
  font: 600 16px/1 var(--font-body); cursor: pointer;
}
/* Primary is RED, and the label is sized to earn it: white on #FE0000 is
   4.03:1, which fails AA for normal text but PASSES AA Large. AA Large starts
   at 18.66px bold, so the label is 19px/700 and no smaller. Shrink this text
   and the button stops being accessible. */
.btn--go {
  background: var(--action); color: #fff;
  font: 700 19px/1 var(--font-body); padding: 14px 26px;
}
.btn--go:hover { background: var(--action-deep); }
.btn--back { background: transparent; color: var(--ink-soft); border-color: var(--hair); }
.err { color: var(--action-deep); font-size: 14px; margin: 12px 0 0; }

/* ---- Result ---- */
.res__head { margin-bottom: 22px; }
.res__unit {
  font-family: var(--font-head); font-size: clamp(1.5rem,1.2rem + 1.4vw,2.2rem);
  font-weight: 700; color: var(--action);   /* >=24px, AA Large on white */
}
.res__use { color: var(--ink-soft); }
.res__note {
  background: var(--panel); border: 1px solid var(--hair);
  border-radius: var(--radius); padding: 14px 16px; margin: 18px 0; font-size: 15px;
}
.res__spend { font-family: var(--font-head); font-size: 1.5rem; font-weight: 700; margin: 4px 0; }
.res__spend small { display: block; font: 400 14px/1.4 var(--font-body); color: var(--ink-soft); margin-top: 6px; }

/* The procurement line is the sentence a superintendent reads. Largest non-
   headline text on the page, and it never sits on red. */
.po {
  border: 2px solid var(--action); border-radius: 8px; padding: 20px; margin: 22px 0;
  background: #fff;
}
.po__label { font: 600 12px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--action); }
.po__line { font-family: var(--font-head); font-size: 1.15rem; font-weight: 700; margin: 10px 0 0; }

.pillars { display: grid; gap: 14px; grid-template-columns: repeat(3, 1fr); margin: 24px 0; }
.pillar { border-top: 3px solid var(--slate); padding-top: 12px; }
.pillar h3 { margin-bottom: 4px; }
.pillar p { margin: 0; font-size: 14px; color: var(--ink-soft); }

.res__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 24px; }

/* Category art stands in for photography. Line art, not a "photo coming" box:
   a visible placeholder telling a client something is missing is worse than
   omitting it. Swap the <img src> when Apollo sends press-kit shots. */
/* Fixed HEIGHT, not aspect-ratio. With `place-items: center` the grid child is
 * not stretched, so `height: 100%` on the img had nothing to resolve against
 * and a 744x880 product shot rendered 1094px tall inside a ~625px box, blowing
 * the card open. Measured 929x1094 in the browser. */
/* Product panel, anchored to a real shipped screen rather than invented.
 *
 * Reference: GTE (mobbin.com/sites/sections/f7c70eda-0182-46ac-972e-8d85d06ef85d)
 * - dark panel, product lit from behind, monospace callouts in the margins,
 * hairline tick marks. Restraint borrowed from Square's hardware sections.
 *
 * ⛔ Still NOT the "futuristic" default: no purple or teal, no glassmorphism,
 * no blur, no mesh. The only colours are Apollo's own black, red and white.
 * Black already carries the pillars band on this page, so the panel reads as
 * part of the brand rather than a borrowed sci-fi treatment. A mostly-white
 * robot on black also has far more separation than it had on white, which was
 * the actual problem with the previous version.
 */
.shot {
  position: relative; isolation: isolate;
  background:
    /* the light the unit stands in */
    radial-gradient(58% 72% at 50% 62%, rgba(255,255,255,.16) 0%, rgba(255,255,255,0) 70%),
    /* floor line */
    linear-gradient(to right, transparent 6%, rgba(254,0,0,.85) 6%, rgba(254,0,0,.85) 94%, transparent 94%)
      0 calc(100% - 30px) / 100% 1px no-repeat,
    var(--black);
  border: 1px solid var(--black); border-radius: 8px;
  height: clamp(190px, 26vw, 300px); margin-bottom: 18px; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
/* ⛔ An earlier .shot design (tick bars, a bottom scrim, a top-left tag) used
 * to live here and was silently overridden by the corner-tick block further
 * down, which redefines the SAME two pseudo-elements. The cascade merged them
 * per-property rather than replacing them: the tick-bar `background` and
 * `right` survived into an 18px box, the scrim collapsed to an invisible 18px
 * square still carrying `z-index:-1`, and .shot__tag inherited `top:14px` from
 * here and `bottom:10px` from there, so its box stretched the full panel.
 * Deleted rather than merged; the later block is the intended design.
 * Found by kimi_k3 2026-09-18. */
.shot__tag::before { content: "// "; color: var(--action); }
.shot img { max-width: 100%; max-height: 100%; object-fit: contain;
            padding: 26px 10px 34px; position: relative; z-index: 1; }
.shot svg { width: min(64%, 260px); height: auto; opacity: .9; }
/* Several jobs: smaller stage so the printed brief stays one page. Scoped to
   .stage, not .shot: `.job + .job .shot` (0,3,0) beat `.stage .shot` and left a
   200px shot floating in a 290px stage. Measured by Fable, 2026-09-18. */
.job + .job .stage { min-height: clamp(150px, 19vw, 215px); }

@media (max-width: 720px) {
  /* One action in the first viewport. Measured at 390x844: the advisor card
     started at y~1080, entirely below the fold, so the first screen was all
     headline and no tool. Tightening the hero brings step 1 into view. */
  .hero { padding: 20px 0 4px; }
  .hero h1 { max-width: 12ch; }
  .lede { font-size: 17px; }
  .card { margin-top: 18px; }
  .fields, .pillars { grid-template-columns: 1fr; }
  .hdr__tel { padding: 9px 12px; font-size: 14px; }
  .card { padding: 20px 16px; }
}

/* ---- Print: the result IS the leave-behind. Cmd-P gives one page. ---- */
@media print {
  @page { margin: 14mm; }
  body { background: #fff; font-size: 11pt; }
  .hdr__tel, .nav, .res__actions, .noprint { display: none !important; }
  .card { border: none; box-shadow: none; padding: 0; margin: 0; }
  .po { border-color: var(--ink); break-inside: avoid; }
  .pillars { break-inside: avoid; }
  h1 { font-size: 22pt; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }
}

/* ---- Black band. The logo is 45% black, so black is a real brand surface and
   not just text. White on black is 21:1 and red on black is 5.21:1, which
   passes AA at NORMAL size, better than red on white manages. This is where
   the palette gets to be loud without an accessibility cost.
   Placed before the page end, not after: a dark CTA band stacked above a dark
   footer makes the page appear to end twice. ---- */
.band {
  background: var(--black); color: #fff;
  padding: 52px 0; margin: 8px 0 0;
}
.band .wrap { padding: 0 24px; }
.band h2 { color: #fff; }
.band .eyebrow { color: var(--action); }        /* 5.21:1 on black */
.band .pillar { border-top: 3px solid var(--action); }
.band .pillar h3 { color: #fff; }
.band .pillar p { color: #c9c9c9; }             /* 11.6:1 on black */
.band__foot {
  border-top: 1px solid #2a2a2a; margin-top: 34px; padding-top: 20px;
  display: flex; flex-wrap: wrap; gap: 14px; align-items: center;
  justify-content: space-between;
}
.band__foot p { margin: 0; color: #c9c9c9; font-size: 15px; max-width: 58ch; }
.band__tel {
  display: inline-flex; align-items: center; min-height: 52px;
  background: var(--action); color: #fff; text-decoration: none;
  font: 700 19px/1 var(--font-body); padding: 0 26px; border-radius: var(--radius);
  white-space: nowrap;
}
.band__tel:hover { background: #fff; color: var(--black); }
@media print { .band { background: #fff; color: var(--ink); padding: 0; }
  .band h2, .band .pillar h3 { color: var(--ink); } .band .pillar p { color: #444; } }

/* ---- Multi-job brief. A district covering floors AND turf is a normal ask,
   and Apollo's own pitch ("one vendor, one relationship") is strongest exactly
   there, so the brief stacks rather than forcing one choice. ---- */
.job + .job { border-top: 1px solid var(--hair); margin-top: 26px; padding-top: 26px; }
.job__n {
  font: 500 12px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  color: var(--action); margin: 0 0 12px;
}
.res__total {
  border-top: 2px solid var(--black); margin-top: 26px; padding-top: 16px;
  font-size: 17px;
}
.res__total strong { font-family: var(--font-head); font-size: 1.25rem; }
@media print { .job { break-inside: avoid; } }
.qhint { font-size: 14px; color: var(--ink-soft); margin: 10px 0 18px; }

@media print { .shot { height: 130px; } }

/* Corner ticks, drawn not imaged. Two elements, four corners, no extra markup. */
.shot::before, .shot::after {
  content: ""; position: absolute; width: 18px; height: 18px; pointer-events: none;
}
/* var(--black) here drew black ticks on the black panel, i.e. nothing. This
 * block was written against a white panel. kimi_k3 2026-09-18. */
.shot::before {
  top: 10px; left: 10px;
  border-top: 2px solid rgba(255,255,255,.55); border-left: 2px solid rgba(255,255,255,.55);
}
.shot::after {
  bottom: 10px; right: 10px;
  border-bottom: 2px solid rgba(255,255,255,.55); border-right: 2px solid rgba(255,255,255,.55);
}
/* The unit's own name, set like a drawing callout. */
.shot__tag {
  position: absolute; left: 14px; bottom: 10px;
  font: 500 11px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase;
  /* NOT --ink-soft. This block was written for a white panel and lands on the
     black one, where #5c5c5c measures 3.14:1 at 11px, below AA's 4.5:1, on the
     only label naming the unit in the shot. Measured in the browser, not read
     off the source. The @media print block below restores ink for paper, where
     the panel really is white. kimi_k3 2026-09-18. */
  color: rgba(255,255,255,.72);
}
@media print {
  /* Ink. A black panel is not something a district prints. */
  .shot { background: #fff; border-color: var(--hair); height: 130px; }
  .shot::before, .shot::after { display: none; }
  .shot__tag { color: var(--ink-soft); }
  .shot__tag::before { color: var(--ink-soft); }
}

/* ---- Shot + specs, side by side. The specs answer the one question a
   facilities director has looking at a machine: will it do my building in the
   hours I have. ---- */
/* min-height, and the spec column sets the real height. A fixed height with
   overflow:hidden clipped the CC1 Pro card at 1024 wide: the COVERAGE label lost
   its top and the source line was cut mid-sentence (spec scrollHeight 218 in a
   193px box). The earlier height:auto attempt grew to 534px because the img's
   natural height drove the row; taking the img out of flow (absolute, inside the
   relative .shot) stops that, so the row is exactly the taller of min-height and
   the spec. gpt6_astra 2026-09-18, measured at 1024, 1280, 1440. */
.stage {
  display: grid; grid-template-columns: 1.3fr 1fr; gap: 16px;
  align-items: stretch; min-height: clamp(210px, 23vw, 290px);
}
.stage .shot { margin-bottom: 0; height: auto; }   /* grid stretch sets it, not the .shot clamp */
.stage .shot img { position: absolute; inset: 0; width: 100%; height: 100%; box-sizing: border-box; }
.stage { margin-bottom: 18px; }
.spec {
  margin: 0; padding: 16px 20px; border: 1px solid var(--hair); border-radius: 8px;
  background: var(--panel); display: flex; flex-direction: column; justify-content: center;
  overflow: hidden;
}
.spec__row { display: grid; gap: 2px; padding: 9px 0; }
.spec__row + .spec__row { border-top: 1px solid var(--hair); }
.spec dt {
  font: 500 11px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-soft);
}
.spec dd { margin: 0; font: 600 15px/1.3 var(--font-body); color: var(--ink); }
.spec__src {
  margin: 14px 0 0; font-size: 11.5px; line-height: 1.45; color: var(--ink-soft);
  border-top: 1px solid var(--hair); padding-top: 10px;
}
@media (max-width: 720px) {
  /* Stack, and let the height be the sum rather than a cap. */
  .stage { grid-template-columns: 1fr; height: auto; }
  /* ⛔ `.job + .job .stage` (0,3,0) OUTRANKS `.stage` (0,1,0), so the second and
     third job kept their 150px desktop cap here while `.stage .shot` alone is
     190px. Measured at 390x844: stage clientHeight 150, scrollHeight 240, so a
     second card overflowed its own panel by 90px into the text below it. The
     three-job demo is exactly this case, and a director scanning the QR code
     reads it on a phone. gpt6_astra 2026-09-18. */
  .job + .job .stage { height: auto; }
  .stage .shot { height: 190px; }
}
@media print {
  /* height:auto and overflow:visible. A fixed 150px with overflow:hidden clipped
     the source attribution, which is the whole point of the panel on a
     leave-behind, and cut the first label in half. Measured at 190mm. */
  .stage { grid-template-columns: 1.2fr 1fr; height: auto; }
  .job + .job .stage { height: auto; }   /* same specificity trap on paper */
  .stage .shot { height: 130px; }
  .shot__art { stroke: var(--black); }   /* white panel on paper, so ink again */
  .spec { background: #fff; overflow: visible; justify-content: flex-start; }
  .spec__src { font-size: 9pt; }
}
