/* Full viewport entrance and a responsive product page. No thread or player UI. */
.project-page--thunderlink { background:#ecebe6; color:#191c20; }
.project-page--thunderlink::before { display:none; }
.project-page--thunderlink .nav { color:#e9ecf1; }
.project-page--thunderlink header.nav::before { background:#08090b9c; }
.tl-page { --page-gutter:clamp(1.25rem,4.5vw,6rem); }
.thunderlink-entrance { position:relative; width:100%; height:100svh; height:100dvh; min-height:20rem; overflow:hidden; background:#08090b; }
.entrance-player,.entrance-stage { position:absolute; inset:0; width:100%; height:100%; }
.entrance-stage { overflow:hidden; isolation:isolate; }
.entrance-stage > :is(img,video) { position:absolute; inset:0; display:block; width:100%; height:100%; object-fit:cover; object-position:50% 50%; }
.entrance-stage > img { z-index:0; }
.entrance-stage > video { opacity:0; z-index:1; pointer-events:none; }
.entrance-stage .project-film__video { aspect-ratio:auto; mix-blend-mode:normal; transition:none; }
/* Wide screens: the interface film fills the viewport under the nav, like the clean footage did.
   Portrait: a 16:9 strip below the nav, so cover crops nothing there. */
@media(max-aspect-ratio:1/1) {
 .thunderlink-entrance:has([data-framing="interface"]) { height:calc(68px + 56.25vw); min-height:0; }
 .entrance-player[data-framing="interface"] { top:68px; height:calc(100% - 68px); }
}
.tl-wrap { margin-inline:var(--page-gutter); }
.tl-intro { padding-block:clamp(4rem,10vw,10rem) clamp(4rem,8vw,8rem); }
.tl-eyebrow { margin:0 0 1.8rem; font:500 .68rem/1.4 var(--font-display,sans-serif); letter-spacing:.13em; text-transform:uppercase; }
.tl-intro__name { margin:0 0 clamp(2.5rem,6vw,6rem); font:500 clamp(3.5rem,10vw,10.5rem)/.95 var(--font-display,sans-serif); letter-spacing:-.06em; }
.tl-intro__body { display:grid; grid-template-columns:minmax(0,1.55fr) minmax(0,1fr); gap:8vw; align-items:end; }
.tl-page h2 { font-family:var(--font-display,sans-serif); font-weight:500; letter-spacing:-.045em; }
.tl-intro__body h2 { margin:0; max-width:18ch; font-size:clamp(2.4rem,4.8vw,5.2rem); line-height:1.05; }
.tl-intro__body p { margin:0; font-size:clamp(1rem,1.3vw,1.3rem); line-height:1.65; max-width:41ch; color:#51575e; }
.tl-specs { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:2rem; border-top:1px solid #191c2030; margin-top:clamp(3rem,6vw,6rem); padding-top:2rem; }
.tl-specs dt { font:500 clamp(1.6rem,2.6vw,2.8rem)/1.1 var(--font-display,sans-serif); letter-spacing:-.03em; }
.tl-specs dd { margin:.7rem 0 0; font-size:.78rem; color:#626971; }
.tl-feature { display:grid; grid-template-columns:minmax(0,1.3fr) minmax(0,1fr); gap:clamp(2rem,7vw,8rem); align-items:center; padding-block:clamp(3rem,6vw,6rem); border-top:1px solid #191c2026; scroll-margin-top:5rem; }
.tl-feature figure { margin:0; min-width:0; }
.tl-feature img { display:block; width:100%; aspect-ratio:4/3; object-fit:cover; }
.tl-feature figcaption { color:#666e77; font-size:.65rem; letter-spacing:.06em; padding-top:.8rem; }
.tl-feature__copy h2 { font-size:clamp(2.25rem,4.3vw,4.8rem); line-height:1.05; margin:0 0 1.7rem; max-width:16ch; }
.tl-feature__copy>p:last-child { font-size:clamp(1rem,1.25vw,1.2rem); color:#51575e; line-height:1.65; max-width:43ch; margin:0; }
.tl-feature--reverse figure { order:2; }
.tl-feature--reverse .tl-feature__copy { order:1; }
.tl-feature--reverse { grid-template-columns:minmax(0,1fr) minmax(0,1.3fr); }
.tl-analysis { margin-top:clamp(3rem,6vw,6rem); background:#151b20; color:#e8ecf0; padding:clamp(4rem,8vw,9rem) var(--page-gutter); scroll-margin-top:4rem; }
.tl-analysis__head { display:grid; grid-template-columns:minmax(0,1.5fr) minmax(0,1fr); gap:8vw; align-items:end; margin-bottom:clamp(3rem,6vw,6rem); }
.tl-analysis h2 { font-size:clamp(2.6rem,5.5vw,6rem); line-height:1.03; margin:0; max-width:17ch; }
.tl-analysis__head>p { color:#a9b4bf; font-size:clamp(1rem,1.3vw,1.25rem); line-height:1.65; max-width:43ch; margin:0; }
.tl-analysis__grid { display:grid; grid-template-columns:1fr 1fr; gap:4vw; }
.tl-analysis article { border-top:1px solid #ffffff35; padding-top:1.5rem; }
.tl-analysis h3 { font:500 clamp(1.4rem,2.1vw,2rem)/1.2 var(--font-display,sans-serif); letter-spacing:-.025em; margin:0 0 1rem; }
.tl-analysis article p { color:#a9b4bf; line-height:1.65; max-width:52ch; margin:0; }
.tl-contact { display:flex; gap:2rem; justify-content:space-between; align-items:end; padding:clamp(4rem,9vw,10rem) var(--page-gutter); background:#08090b; color:#e9ecf1; }
.tl-contact h2 { font-size:clamp(2rem,5.2vw,6rem); line-height:1.05; margin:0; white-space:nowrap; }
.tl-contact a { display:inline-flex; align-items:center; gap:2rem; padding:1rem 0; border-bottom:1px solid #e9ecf1; color:#e9ecf1; white-space:nowrap; }
.project-page--thunderlink .footer { background:#08090b; color:#e9ecf1; }
.tl-page a:focus-visible { outline:2px solid currentColor; outline-offset:.4rem; }
@media(max-width:850px) {
 .tl-intro__body,.tl-analysis__head { grid-template-columns:1fr; gap:2rem; }
 .tl-intro__body p,.tl-analysis__head>p { max-width:50ch; }
 .tl-feature,.tl-feature--reverse { grid-template-columns:1fr; gap:2rem; }
 .tl-feature figure,.tl-feature--reverse figure { order:2; }
 .tl-feature .tl-feature__copy,.tl-feature--reverse .tl-feature__copy { order:1; }
 .tl-feature__copy h2 { max-width:19ch; }
 .tl-specs { grid-template-columns:1fr 1fr; gap:2rem 1rem; }
 .tl-contact { display:block; }
 .tl-contact a { margin-top:2.5rem; }
}
@media(max-width:540px) {
 .tl-analysis__grid { grid-template-columns:1fr; gap:2.5rem; }
 .tl-intro__name { font-size:clamp(3.2rem,14vw,5rem); }
 .tl-feature img { aspect-ratio:5/4; }
}
@media(max-height:400px) { .thunderlink-entrance { min-height:0; } }
/* Spec row sits centred between its top rule and the next section's rule. Text boxes are trimmed
   to the capitals' top and the last baseline so the centring is optical, not line-box based. */
.tl-intro { padding-bottom:0; }
.tl-specs { padding-block:clamp(2.5rem,5vw,5rem); margin-bottom:0; }
.tl-specs dt { text-box:trim-start cap alphabetic; }
.tl-specs dd { text-box:trim-end cap alphabetic; }
/* product.css (live reverse-engineering + EM sections) sizes `.tl-intro h1`; keep the large page name. */
.tl-intro .tl-intro__name { font:500 clamp(3.5rem,10vw,10.5rem)/.95 var(--font-display,sans-serif); letter-spacing:-.06em; }
@media(max-width:540px) { .tl-intro .tl-intro__name { font-size:clamp(3.2rem,14vw,5rem); } }
/* Undo product.css side effects on the earlier sections: keep the name's gap and natural heading wraps. */
.tl-intro .tl-intro__name { margin:0 0 clamp(2.5rem,6vw,6rem); }
.tl-page :is(.tl-intro,.tl-feature,.tl-analysis,.tl-contact) h2 { text-wrap:wrap; }
/* Live reverse-engineering + EM sections: same rules and heading scale as the surrounding features. */
.tl-content--diagrams { margin-block:0; padding-block:clamp(3rem,6vw,6rem); border-top:1px solid #191c2026; }
.tl-content--diagrams .tl-section-heading h2 { font-size:clamp(2.2rem,4.3vw,4.7rem); line-height:1.05; }
/* Intro: title + copy on the left, the animated Thunderlink window demo on the right. */
.tl-intro__top { display:grid; grid-template-columns:max-content minmax(0,1fr); gap:clamp(2rem,4vw,5rem); align-items:center; }
.tl-intro__lead { display:flex; flex-direction:column; min-width:0; }
.tl-intro__lead .tl-intro__body { display:flex; flex-direction:column; align-items:start; gap:1.25rem; }
.tl-intro__lead .tl-intro__name { margin-bottom:clamp(1.5rem,3.5vw,3.5rem); }
.tl-intro__lead .tl-intro__body h2 { max-width:none; font-size:clamp(1.9rem,3.2vw,3.5rem); }
.tl-intro__lead .tl-intro__body p { max-width:46ch; font-size:clamp(1rem,1.15vw,1.2rem); }
.tl-intro__demo { min-width:0; }
@media(max-width:960px) {
 .tl-intro__top { grid-template-columns:1fr; }
 .tl-intro__lead { display:contents; }
 .tl-intro__lead .tl-intro__name { order:1; }
 .tl-intro__demo { order:2; }
 .tl-intro__lead .tl-intro__body { order:3; }
}
/* Light mode for the demo frame and windows (window screenshots to be retaken in light mode). */
.tl-intro .tl-demo__frame { background:#f8f7f3; border-color:#191c2026; }
.tl-intro .tl-demo__bar { background:#e6e4de; border-bottom-color:#191c201a; }
.tl-intro .tl-demo__bar span { background:#bdbab2; }
.tl-intro .tl-demo__screen { background-image:linear-gradient(rgba(212,43,30,.07) 1px,transparent 1px),linear-gradient(90deg,rgba(212,43,30,.07) 1px,transparent 1px); }
.tl-intro .tl-win { background:#fffffff2; border-color:#191c2026; }
/* The script tweens dark drop shadows inline; matching only their end values made in-between frames
   flip back to the dark shadow (flicker). One steady soft shadow for every window instead. */
.tl-intro .tl-win { box-shadow:0 14px 34px rgba(25,28,32,.16) !important; }
/* Exploded scenes push windows past the demo's box: keep it off the page edge and never scroll sideways. */
.tl-intro__demo { padding-left:clamp(1.5rem,4vw,4rem); padding-right:clamp(0rem,4.5vw,3.5rem); }
@media(max-width:960px) { .tl-intro__demo { padding-left:0; padding-right:0; } }
.tl-page { overflow-x:clip; }
/* Same rule and spacing between the two diagram sections as between every other section. */
.tl-content--diagrams { gap:0; }
.tl-content--diagrams > .tl-content-section + .tl-content-section { margin-top:clamp(3rem,6vw,6rem); padding-top:clamp(3rem,6vw,6rem); border-top:1px solid #191c2026; }
/* Image sections (terrain, live coverage): exactly the screen height below the fixed nav (68px + its 1px rule); the image fills it minus the page
   gutter above and below, so its top/bottom margin matches the side margin. Side-by-side layouts only. */
@media(min-width:850.02px) {
 .tl-page .tl-feature { box-sizing:border-box; height:calc(100svh - var(--nav-h,69px)); padding-block:calc(var(--site-gutter) - 1px) var(--site-gutter); align-items:stretch; }
 .tl-page .tl-feature figure { position:relative; height:100%; min-height:0; }
 .tl-page .tl-feature img { width:100%; height:100%; aspect-ratio:auto; object-fit:cover; }
 .tl-page .tl-feature figcaption { position:absolute; left:.9rem; bottom:.75rem; padding:0; color:#fff; text-shadow:0 1px 6px rgba(0,0,0,.55); }
 .tl-page .tl-feature__copy { align-self:center; }
}
/* Reverse-engineering stage cards: fill only, no outline. */
.tl-content--diagrams .eng-stage { border:0; }
/* Opening section: one block the height of the screen below the nav, gutter-sized margin top and bottom,
   title + demo centred above and the stats row closing it (no divider above the stats). */
.tl-page .tl-intro .tl-specs { border-top:0; margin-top:clamp(2.5rem,5vw,5rem); padding-block:0; }
@media(min-width:850.02px) {
 .tl-page .tl-intro { box-sizing:border-box; min-height:calc(100svh - var(--nav-h,69px)); display:flex; flex-direction:column; padding-block:calc(var(--site-gutter) * 2.5); }
 /* Title block anchored at the top, stats pushed to the bottom: the padding shows as-is at both ends. */
 .tl-page .tl-intro .tl-specs { margin-top:auto; padding-top:clamp(2.5rem,5vw,5rem); }
}
@media(max-width:850px) { .tl-page .tl-intro { padding-bottom:clamp(2.5rem,5vw,5rem); } }
/* Fade-in for section elements (reveal.js). Hidden only once the script has marked the page. */
@media (prefers-reduced-motion: no-preference) {
 .tl-reveal .reveal { opacity:0; }
 .tl-reveal .reveal.is-in { opacity:1; transition:opacity .9s cubic-bezier(.22,1,.36,1) var(--reveal-delay,0ms); }
}

/* Terrain compare: three renders of one view (coverage | imagery | elevation), two draggable dividers. */
.tl-compare__frame { --knob:2rem; position:relative; aspect-ratio:16/9; overflow:hidden; background:#08090b; cursor:ew-resize; touch-action:pan-y; user-select:none; -webkit-user-select:none; }
.tl-feature .tl-compare__img { position:absolute; inset:0; width:100%; height:100%; aspect-ratio:auto; object-fit:cover; pointer-events:none; }
.tl-compare__img--mid { clip-path:inset(0 calc(100% - var(--b)) 0 0); }
.tl-compare__img--top { clip-path:inset(0 calc(100% - var(--a)) 0 0); }
.tl-compare__handle { position:absolute; top:0; bottom:0; width:2px; margin-left:-1px; background:#fff; pointer-events:none; }
.tl-compare__handle--a { left:var(--a); }
.tl-compare__handle--b { left:var(--b); }
.tl-compare__handle::after { content:""; position:absolute; top:50%; left:50%; width:var(--knob); height:var(--knob); transform:translate(-50%,-50%); border-radius:50%; background:#fff center/1.1rem no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23191c20' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6l-6 6 6 6M15 6l6 6-6 6'/%3E%3C/svg%3E"); }
.tl-compare__label { position:absolute; top:.9rem; padding:.3rem .55rem; background:#08090bb3; color:#e9ecf1; font-size:.62rem; letter-spacing:.08em; text-transform:uppercase; white-space:nowrap; pointer-events:none; transition:opacity .2s; }
.tl-compare__label--start { left:.9rem; }
.tl-compare__label--mid { left:calc((var(--a) + var(--b)) / 2); transform:translateX(-50%); }
.tl-compare__label--end { right:.9rem; }
.tl-compare[data-hide~="start"] .tl-compare__label--start, .tl-compare[data-hide~="mid"] .tl-compare__label--mid, .tl-compare[data-hide~="end"] .tl-compare__label--end { opacity:0; }
.tl-compare__range { position:absolute; width:1px; height:1px; margin:0; opacity:0; pointer-events:none; }
.tl-compare__frame:has(.tl-compare__range--a:focus-visible) .tl-compare__handle--a::after,
.tl-compare__frame:has(.tl-compare__range--b:focus-visible) .tl-compare__handle--b::after { outline:2px solid #d42b1e; outline-offset:3px; }
@media(max-width:540px) { .tl-compare__frame { --knob:1.8rem; } .tl-compare__label { font-size:.55rem; top:.6rem; } .tl-compare__label--start { left:.6rem; } .tl-compare__label--end { right:.6rem; } }
/* In the full-height image sections the compare keeps its 16:9 frame (cropping would cut off the minimap and elevation key),
   centred in the column with the caption under it. */
@media(min-width:850.02px) {
 .tl-page .tl-feature figure.tl-compare { display:flex; flex-direction:column; justify-content:center; }
 .tl-page .tl-feature .tl-compare__frame { width:100%; max-height:calc(100% - 2rem); aspect-ratio:16/9; }
 .tl-page .tl-feature .tl-compare__img { height:100%; }
 .tl-page .tl-feature .tl-compare figcaption { position:static; padding-top:.8rem; color:#666e77; text-shadow:none; }
}
/* Give the compare more of the row than a plain image gets. */
@media(min-width:850.02px) { .tl-page .tl-feature:has(.tl-compare) { grid-template-columns:minmax(0,1.7fr) minmax(0,1fr); gap:clamp(2rem,5.5vw,6rem); } }
@media(min-width:850.02px) { .tl-page .tl-feature:has(.tl-compare) .tl-feature__copy { justify-self:end; text-align:right; } .tl-page .tl-feature:has(.tl-compare) .tl-feature__copy > * { margin-left:auto; } }
/* Terrain heading always breaks as "The terrain is part / of the picture." side by side; flows freely when stacked. */
@media(min-width:850.02px) { .tl-page .tl-feature:has(.tl-compare) .tl-feature__copy h2 { max-width:none; white-space:nowrap; font-size:clamp(2rem,3.7vw,4.8rem); } }
@media(max-width:850px) { .tl-br-wide { display:none; } }
/* Reverse engineering card 02: the network + gears drawing only filled ~74% of its card's width; widen its view so the drawing
   reaches the same inner margins as card 01's table (the view's own transparent margin overhangs the card padding). */
.tl-content .panel-inference .eng-art > .eng-figure { width:121.5%; margin-inline:-10.75%; }
/* Drones section (2026-10-15): 16:9 photo at the same width as the terrain and coverage figures above. */
@media(min-width:851px){.tl-page #drones{grid-template-columns:minmax(0,1.7fr) minmax(0,1fr);gap:clamp(2rem,5.5vw,6rem)}}
.tl-page #drones figure{height:auto;aspect-ratio:16/9;align-self:center}
.tl-page #drones img{height:100%;aspect-ratio:auto}
