/* DigitalTwin HL sandbox.
   Takes its structure from placeenginehl.com — near-black ground, white
   headline with the turn of the sentence in accent, tracked eyebrow, hairline
   panel grid, solid accent pill and an outlined secondary — with amber in place
   of that site's crimson so the sandbox is recognisably a sibling, not a copy. */

:root {
    --ground:   #0B0B0D;
    --panel:    #141419;
    --panel-2:  #1A1A21;
    --rule:     #24242C;
    --text:     #F4F4F6;
    --muted:    #9A9AA6;
    --accent:   #F0A93B;
    --accent-d: #C9862A;
    --live:     #3FC5AA;
    --measure:  62ch;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
    background: var(--ground);
    color: var(--text);
    font-family: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
    font-size: 16px;
    line-height: 1.6;
    font-variant-numeric: tabular-nums;
    -webkit-font-smoothing: antialiased;
}

.wrap { max-width: 72rem; margin: 0 auto; padding-inline: 1.5rem; }
a { color: var(--text); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- masthead -------------------------------------------------------- */

.masthead { border-bottom: 1px solid var(--rule); position: sticky; top: 0; background: var(--ground); z-index: 20; }
.masthead .wrap { display: flex; align-items: center; gap: .9rem; padding-block: 1.1rem; }

/* lowercase wordmark with a superscript badge, as on placeenginehl.com */
.mark { display: inline-flex; align-items: flex-start; gap: .28rem; text-decoration: none; font-weight: 600; font-size: 1.25rem; letter-spacing: -0.02em; }
.mark .badge {
    background: var(--accent); color: #17130A;
    font-size: .5rem; font-weight: 700; line-height: 1;
    padding: .18rem .22rem; border-radius: 2px;
    letter-spacing: .02em; margin-top: .18rem;
}
.mark img { height: 22px; width: auto; display: block; }
.masthead .sub { color: var(--muted); font-size: .9375rem; }
.masthead .firm { margin-left: auto; color: var(--muted); font-size: .875rem; }

/* ---- eyebrow --------------------------------------------------------- */

.eyebrow {
    color: var(--accent);
    font-size: .75rem; font-weight: 600;
    letter-spacing: .16em; text-transform: uppercase;
}

/* ---- hero ------------------------------------------------------------ */

.hero { padding-block: 5rem 3.25rem; border-bottom: 1px solid var(--rule); }
.hero h1 {
    font-stretch: 112%;
    font-weight: 700;
    font-size: clamp(2.1rem, 1.2rem + 3.4vw, 3.9rem);
    line-height: 1.04;
    letter-spacing: -0.028em;
    max-width: 18ch;
    margin-top: 1.1rem;
}
.hero h1 em { font-style: normal; color: var(--accent); }
.hero p { color: var(--muted); margin-top: 1.25rem; max-width: var(--measure); font-size: 1.0625rem; }

/* stat tiles in a hairline grid, as on the marketing site */
.tiles { display: grid; grid-template-columns: repeat(4, 1fr); border: 1px solid var(--rule); border-radius: 4px; margin-top: 2.75rem; overflow: hidden; }
.tiles div { padding: 1.35rem 1.25rem; border-right: 1px solid var(--rule); }
.tiles div:last-child { border-right: 0; }
.tiles b { display: block; font-size: 1.6rem; font-weight: 700; letter-spacing: -0.02em; }
.tiles b span { color: var(--accent); }
.tiles small { color: var(--muted); font-size: .8125rem; }

/* ---- project sheets -------------------------------------------------- */

.sheets { padding-block: 1rem 2rem; }
.sheet {
    display: grid; grid-template-columns: 22rem minmax(0, 1fr); gap: 2rem;
    padding-block: 2.5rem; border-bottom: 1px solid var(--rule); align-items: start;
}
.sheet:last-child { border-bottom: 0; }

.shot { border: 1px solid var(--rule); border-radius: 4px; overflow: hidden; background: var(--panel); aspect-ratio: 16 / 10; }
.shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.shot.empty { display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: .8125rem; text-align: center; padding: 1rem; }

.sheet h2 { font-stretch: 108%; font-weight: 700; font-size: 1.75rem; letter-spacing: -0.02em; line-height: 1.15; }
.sheet h2 a { text-decoration: none; }
.sheet h2 a:hover { color: var(--accent); }
.sheet .place { color: var(--muted); font-size: .9375rem; margin-top: .2rem; }
.sheet p.blurb { color: var(--muted); margin-top: .9rem; max-width: var(--measure); }
.sheet .meta { display: flex; gap: 1.25rem; flex-wrap: wrap; margin-top: 1rem; color: var(--muted); font-size: .8125rem; }
.sheet .meta b { color: var(--text); font-weight: 500; }

.actions { display: flex; align-items: center; gap: 1rem; margin-top: 1.5rem; flex-wrap: wrap; }

/* ---- buttons --------------------------------------------------------- */

.btn {
    font: inherit; font-weight: 600;
    background: var(--accent); color: #17130A;
    border: 1px solid var(--accent); border-radius: 999px;
    padding: .72rem 1.4rem; cursor: pointer;
    text-decoration: none; display: inline-block; white-space: nowrap;
    transition: filter .15s ease;
}
.btn:hover { filter: brightness(1.07); }
.btn[disabled] { background: transparent; color: var(--muted); border-color: var(--rule); cursor: not-allowed; filter: none; }
.btn.ghost { background: transparent; color: var(--text); border-color: var(--rule); }
.btn.ghost:hover { border-color: var(--muted); filter: none; }

.state { font-size: .875rem; color: var(--muted); }
.state.free { color: var(--live); }
.state.busy { color: var(--accent); }

/* ---- capacity ribbon ------------------------------------------------- */

.capacity { display: flex; align-items: center; gap: .85rem; }
.ribbon { display: flex; gap: 5px; }
.ribbon i { display: block; width: 9px; height: 26px; border: 1px solid var(--rule); border-radius: 2px; transition: background-color .4s ease, border-color .4s ease; }
.ribbon i.occupied { background: var(--text); border-color: var(--text); }
.ribbon i.starting { border-color: var(--accent); animation: breathe 1.6s ease-in-out infinite; }
.capacity .count { color: var(--muted); font-size: .8125rem; }
.capacity .count b { color: var(--text); font-weight: 500; }
@keyframes breathe { 0%, 100% { opacity: 1 } 50% { opacity: .35 } }

/* ---- project page: a splash that fills its frame ---------------------- */

/* These pages are embedded in an iframe on another site. Opened that way the
   masthead and footer read as a second website inside the first, so they go. */
html.embedded .masthead,
html.embedded .foot { display: none; }

/* Embedded, the splash IS the page: it fills the frame edge to edge. */
html.embedded .splash { min-height: 100vh; }

/* Standalone it must not. Full-bleed on a 1920-wide window renders the still at
   roughly its native size, so the model's own HUD -- scenario chips, minimap,
   control hints -- balloons and competes with the type, which ends up strung
   along the bottom of an enormous image. Contained to the site's own column at
   16:9 it reads as a hero and the still sits at a sane scale, the same way it
   does inside a frame. */
html:not(.embedded) .splash {
    min-height: 26rem;
    width: min(100% - 3rem, 72rem);
    margin: 2rem auto 0;
    aspect-ratio: 16 / 9;
    max-height: calc(100vh - 9rem);
    border: 1px solid var(--rule);
    border-radius: 6px;
    overflow: hidden;
    padding-block: 2rem 4.5rem;
}
/* The inner column already has the page gutter; inside the card it only needs
   a modest inset, or the text starts a long way from the card edge. */
html:not(.embedded) .splash-inner { padding-inline: 2.25rem; max-width: none; }
html:not(.embedded) .splash h1 { font-size: clamp(1.9rem, 1.2rem + 2.2vw, 3rem); }
html:not(.embedded) .splash .lede { font-size: 1.0625rem; }

/* Narrow, a fixed 16:9 box is shorter than the words it has to hold, and since
   the content sits at the bottom behind overflow:hidden it was the eyebrow and
   the title that got cut off the top. Below this width the card stops being a
   fixed ratio and simply grows to fit. */
@media (max-width: 48rem) {
    html:not(.embedded) .splash {
        aspect-ratio: auto;
        height: auto;
        max-height: none;
        min-height: 24rem;
        padding-block: 2.5rem 4.5rem;
    }
    html:not(.embedded) .splash-inner { padding-inline: 1.5rem; }
}

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

.back { color: var(--muted); font-size: .9375rem; text-decoration: none; }
.back:hover { color: var(--text); }

/* Fills whatever the frame gives it rather than assuming a fixed 16:9, so it is
   right at 16:9 and still right when the host sizes the iframe differently.
   min-height rather than height so the content is never clipped in a short frame. */
.splash {
    position: relative;
    /* Standalone the masthead is above this, so the splash must be the viewport
       minus that or the "Learn more" cue falls below the fold. Embedded there is
       no masthead and it takes the whole frame. */
    min-height: calc(100vh - 4.2rem);
    display: flex; flex-direction: column; justify-content: flex-end;
    padding-block: 4rem 5.5rem;
    background-color: var(--panel);
    background-size: cover; background-position: center;
    isolation: isolate;
}
/* The still carries the type, so it is dimmed from the bottom up: dark enough to
   read against at the bottom, clear enough to see the place at the top. */
.splash::after {
    content: ''; position: absolute; inset: 0; z-index: -1;
    background: linear-gradient(to top, rgba(11,11,13,.95) 0%, rgba(11,11,13,.88) 38%, rgba(11,11,13,.55) 68%, rgba(11,11,13,.32) 100%);
}
/* The stills differ per project -- Glen Ellyn's is bright daylight, West
   Dundee's has a sunlit street right where the eyebrow sits -- so the type
   carries its own shadow rather than relying on the gradient alone. */
.splash .eyebrow, .splash h1, .splash .lede { text-shadow: 0 1px 14px rgba(0,0,0,.6); }
.splash-inner { width: 100%; }
.splash h1 {
    font-stretch: 112%; font-weight: 700;
    font-size: clamp(2rem, 1.1rem + 3.4vw, 3.6rem);
    line-height: 1.04; letter-spacing: -0.028em; margin-top: .9rem;
}
.splash .lede { font-size: clamp(1rem, .95rem + .3vw, 1.2rem); margin-top: 1.1rem; max-width: var(--measure); color: var(--text); }
.splash .actions { margin-top: 1.9rem; }
.splash .eyebrow { display: block; }

/* Sits at the foot of the splash so there is a visible way down without it
   competing with the primary action. */
.more-cue {
    position: absolute; left: 50%; transform: translateX(-50%);
    bottom: 1.5rem; z-index: 1;
    color: var(--muted); text-decoration: none;
    font-size: .875rem; font-weight: 500;
    display: inline-flex; align-items: center; gap: .45rem;
    padding: .5rem .95rem; border: 1px solid var(--rule); border-radius: 999px;
    background: rgba(11,11,13,.55);
    transition: color .15s ease, border-color .15s ease;
}
.more-cue::after { content: ''; width: .44rem; height: .44rem; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); }
.more-cue:hover { color: var(--text); border-color: var(--muted); }

.more { scroll-margin-top: 0; }
.back-row { display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap; }

section.block { padding-block: 2.5rem; border-top: 1px solid var(--rule); }
section.block > h3 { font-size: 1.05rem; font-weight: 600; letter-spacing: -0.01em; margin-bottom: 1.25rem; }

/* facts as a hairline definition grid */
.facts { display: grid; grid-template-columns: 14rem minmax(0, 1fr); border: 1px solid var(--rule); border-radius: 4px; overflow: hidden; }
.facts dt { padding: .9rem 1.1rem; border-bottom: 1px solid var(--rule); border-right: 1px solid var(--rule); color: var(--muted); font-size: .875rem; background: var(--panel); }
.facts dd { padding: .9rem 1.1rem; border-bottom: 1px solid var(--rule); }
.facts dt:nth-last-of-type(1), .facts dd:nth-last-of-type(1) { border-bottom: 0; }

/* press + documents */
.links { display: grid; gap: .75rem; }
.link {
    display: block; text-decoration: none; padding: 1.1rem 1.25rem;
    border: 1px solid var(--rule); border-radius: 4px; background: var(--panel);
    transition: border-color .15s ease, background-color .15s ease;
}
.link:hover { border-color: var(--accent); background: var(--panel-2); }
.link .src { color: var(--accent); font-size: .75rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
.link .ttl { display: block; margin-top: .3rem; font-weight: 500; }
.link .note { display: block; margin-top: .3rem; color: var(--muted); font-size: .9375rem; }

.embed { position: relative; padding-top: 56.25%; border: 1px solid var(--rule); border-radius: 4px; overflow: hidden; }
.embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* ---- live stream stage ----------------------------------------------- */

.stage { display: none; position: fixed; inset: 0; background: #000; z-index: 60; }
.stage.on { display: block; }
.stage iframe { width: 100%; height: 100%; border: 0; display: block; }

/* The model's own touch controls need the gestures. Without this the browser
   claims a drag for panning or pinch-zoom before the virtual joysticks ever see
   it, so on a phone the sticks feel dead. Scrolling is locked behind the stage
   for the same reason -- a drag should move the camera, not the page. */
.stage, .stage iframe { touch-action: none; overscroll-behavior: none; }
body.stage-open { overflow: hidden; }
/* One small exit control instead of a bar. Every model puts its own HUD along
   the top -- scenario chips, minimap, the player page's icons -- so anything
   full width covers a control someone needs. Bottom-centre is no good either --
   that is where Glen Ellyn puts its Existing/Proposed buttons and West Dundee
   its control hints. The right edge at mid-height is the one spot all four
   models leave clear, and it stays faint until pointed at so it reads as chrome
   rather than part of the model. */
.stage .exit {
    position: absolute; z-index: 2;
    top: 50%; right: .6rem; transform: translateY(-50%);
    width: 2rem; height: 2rem; line-height: 1;
    display: flex; align-items: center; justify-content: center;
    font: inherit; font-size: 1.15rem;
    background: rgba(11,11,13,.55); color: var(--text);
    border: 1px solid rgba(255,255,255,.25); border-radius: 999px;
    cursor: pointer; opacity: .35;
    transition: opacity .15s ease, background-color .15s ease;
}
.stage .exit:hover, .stage .exit:focus-visible { opacity: 1; background: rgba(11,11,13,.9); }
.stage .msg { position: absolute; inset: 0; display: none; flex-direction: column; align-items: center; justify-content: center; gap: .6rem; text-align: center; padding: 2rem; }
.stage .msg.on { display: flex; }
.stage .msg b { font-size: 1.15rem; font-weight: 600; }
.stage .msg span { color: var(--muted); font-size: .9375rem; }
.stage .msg.error b { color: var(--accent); }

/* ---- footer ---------------------------------------------------------- */

.foot { border-top: 1px solid var(--rule); margin-top: 3rem; }
.foot .wrap { padding-block: 1.75rem 3rem; color: var(--muted); font-size: .875rem; display: flex; gap: 1rem; flex-wrap: wrap; }
.foot .spacer { margin-left: auto; }

/* ---- narrow ---------------------------------------------------------- */

@media (max-width: 62rem) {
    .sheet { grid-template-columns: minmax(0, 1fr); }
    .tiles { grid-template-columns: repeat(2, 1fr); }
    .tiles div:nth-child(2) { border-right: 0; }
    .tiles div:nth-child(1), .tiles div:nth-child(2) { border-bottom: 1px solid var(--rule); }
}
@media (max-width: 40rem) {
    .hero { padding-block: 3rem 2.25rem; }
    .facts { grid-template-columns: minmax(0, 1fr); }
    .facts dt { border-right: 0; padding-bottom: .2rem; background: transparent; }
    .facts dd { padding-top: .2rem; }
    .masthead .firm { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    * { animation: none !important; transition: none !important; }
}
