/* ============================================================
   TOKENS
   Structure, grid, type scale and component metrics are lifted
   from gentle.systems/services. Palette is rotated off Gentle's
   warm brown/clay onto OSINT Industries' violet axis.
   ============================================================ */
:root{
  /* palette - dark is the default; light is opt-in via the toggle */
  --ground:#0c0b10;
  --surface:#181621;
  --surface-hi:#221f2e;
  --ink:#f2f1f6;
  --label:#928da3;
  --muted:#726d81;
  --line:#282435;
  --accent:#9b8afb;
  --accent-wash:#241d3f;
  --accent-line:#4b3d80;
  --on-accent:#0c0b10;
  --shadow:0 10px 40px -12px rgba(0,0,0,.7);
  --block-bg:#1b1826;
  --block-fg-rgb:242,241,246;
  --block-dim-rgb:132,127,148;

  /* type scale (Gentle: font_xl / l / m / s / s_MONO / xs_fixed) */
  --f-xl:clamp(34px,4vw,46px);
  --f-l:clamp(23px,4vw,36px);
  /* vw factors stay under --f-xl's 4vw so a left heading can never
     overtake the H1 at the widths between the two clamps */
  --f-l-lead:clamp(25px,3.6vw,40px);
  --f-l-sub:clamp(20px,3.0vw,31px);
  --f-m:clamp(18px,4vw,24px);
  --f-s:clamp(15px,2vw,18px);
  --f-mono:clamp(12px,4vw,14px);
  --f-xs:12px;

  /* grid */
  --gutter:6px;
  --edge:clamp(20px,6vw,110px);
  /* maxima trimmed from Gentle's 150/300 - this page carries more sections
     than theirs, so the same values totalled far more air. Only the caps move,
     so the vw ramp and every width below ~1080px stay exactly as they were. */
  --rhythm:clamp(72px,10.4vw,128px);
  --rhythm-lg:clamp(120px,20.8vw,224px);

  /* motion */
  --e1:cubic-bezier(0.33,0,0,1);
  --e2:cubic-bezier(0.33,0,0.66,1);

  --font:"Instrument Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
}
:root[data-theme="light"]{
  --ground:#f6f6f7;
  --surface:#eceaf4;
  --surface-hi:#e4e1f0;
  --ink:#17151d;
  --label:#6c6879;
  --muted:#8b8798;
  --line:#dcd9e6;
  --accent:#6938ef;
  --accent-wash:#e5ddfd;
  --accent-line:#c3b2fb;
  --on-accent:#ffffff;
  --shadow:0 10px 40px -12px rgba(23,21,29,.45);
  --block-bg:#17151d;
  --block-fg-rgb:246,246,247;
  --block-dim-rgb:139,135,152;
}

/* ============================================================
   BASE
   ============================================================ */
:root{color-scheme:dark}
:root[data-theme="light"]{color-scheme:light}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--ground);
  color:var(--ink);
  font-family:var(--font);
  font-weight:500;
  font-size:var(--f-s);
  line-height:1.25;
  letter-spacing:-0.005em;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4,p,ul,li,figure,blockquote{margin:0;padding:0}
h1,h2,h3,h4{font-weight:inherit}
ul{list-style:none}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}

/* ============================================================
   TYPE ROLES
   ============================================================ */
.t-xl{font-size:var(--f-xl);line-height:1.1;letter-spacing:-0.015em;text-wrap:balance;font-weight:700}
.t-l{font-size:var(--f-l);line-height:1.2;letter-spacing:-0.008em;text-wrap:balance;font-weight:500}
.t-m{font-size:var(--f-m);line-height:1.25;letter-spacing:-0.005em}
.t-s{font-size:var(--f-s);line-height:1.25;letter-spacing:-0.005em}
.mono{
  font-family:var(--mono);
  font-size:var(--f-mono);
  line-height:1.25;
  letter-spacing:0.04em;
  text-transform:uppercase;
  font-weight:500;
}
/* the hero keeps the heavier cut; every other display line sits at 500 */
.manifesto .t-xl{font-weight:500}
/* left-column headings are the exception - they anchor each module */
.left .t-l{font-weight:700;font-size:var(--f-l-lead)}
.right .t-l{font-size:var(--f-l-sub)}
.dim{color:var(--label)}
.faint{color:var(--muted)}
.tight{padding-right:50px}
@media (max-width:900px){.tight{padding-right:0}}

/* ============================================================
   GRID - 12 columns, 6px gutter, 6vw edge (Gentle exact)
   ============================================================ */
.g{
  display:grid;
  /* minmax(0,1fr) - plain 1fr floors at min-content and blows the grid out */
  grid-template-columns:repeat(12,minmax(0,1fr));
  gap:var(--gutter);
  width:100%;
  padding-inline:var(--edge);
}
.g > *{min-width:0}
.left{grid-column:1/7}
.right{grid-column:7/13}
.full{grid-column:1/13}
.inset{grid-column:2/12}
@media (max-width:900px){
  .left,.right,.inset{grid-column:1/13}
  .left{margin-bottom:28px}
}

/* module: label column + content column, 150px of air below */
.mod{padding-bottom:var(--rhythm)}
.mod--major{padding-bottom:var(--rhythm-lg)}
.stack{display:flex;flex-direction:column;gap:24px;align-items:flex-start}
.stack--tight{gap:12px}
.rows{display:flex;flex-direction:column;gap:var(--gutter);width:100%}
/* themed blocks within a course */
.groups{display:flex;flex-direction:column;gap:34px;width:100%}
.group{display:flex;flex-direction:column;gap:10px;width:100%}

/* ============================================================
   PILL - Gentle: 8px 12px, 40px radius, 26px tall
   ============================================================ */
.pill{
  display:inline-flex;align-items:center;gap:12px;
  min-height:26px;padding:8px 12px;
  border-radius:40px;
  background:var(--surface);
  color:var(--ink);
  font-size:var(--f-mono);
  line-height:1.25;
  letter-spacing:-0.005em;
  transition:background .45s var(--e1),color .45s var(--e1);
}
.pill--wide{justify-content:space-between;width:100%}
a.pill:hover,button.pill:hover{background:var(--accent-wash)}
.pill[aria-current="page"]{background:var(--ink);color:var(--ground)}
.pill svg{flex:none;width:10px;height:10px}
.pills{display:flex;flex-wrap:wrap;gap:var(--gutter)}

/* ============================================================
   HERO EFFECT - video rendered as a halftone of symbols
   ============================================================ */
.hero .left{align-self:center}
.fx-frame{
  width:100%;aspect-ratio:16/9;
  border-radius:15px;overflow:hidden;
  background:var(--surface);
}
.fx-frame canvas{display:block;width:100%;height:100%}
/* WebGL missing or refused: the frame just reads as an empty tile */
.fx-frame canvas[data-symbols-failed]{visibility:hidden}
@media (max-width:900px){ .hero .left{margin-bottom:34px} }

/* ============================================================
   TRUSTED BY - label left, marquee bleeding off the right edge
   ============================================================ */
.mod--tight{padding-bottom:clamp(30px,3.6vw,46px)}
.trust{display:flex;align-items:center;gap:26px}
.trust-label{flex:none;white-space:nowrap}
.trust-strip{
  flex:1 1 auto;min-width:0;overflow:hidden;
  /* run past the page gutter so the band reaches the viewport edge */
  margin-right:calc(var(--edge) * -1);
  -webkit-mask-image:linear-gradient(to right,transparent 0,#000 44px,#000 84%,transparent 100%);
  mask-image:linear-gradient(to right,transparent 0,#000 44px,#000 84%,transparent 100%);
}
.trust-track{display:flex;width:max-content;animation:trust-marquee 64s linear infinite}
.trust-track .pill{margin-right:var(--gutter);white-space:nowrap}
.trust-strip:hover .trust-track{animation-play-state:paused}
@keyframes trust-marquee{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media (max-width:640px){
  .trust{flex-direction:column;align-items:stretch;gap:12px}
  .trust-label{align-self:flex-start}
  /* width:auto - a 100% width fights the negative margin and stops short */
  .trust-strip{
    width:auto;margin-inline:calc(var(--edge) * -1);
    -webkit-mask-image:linear-gradient(to right,transparent 0,#000 24px,#000 88%,transparent 100%);
    mask-image:linear-gradient(to right,transparent 0,#000 24px,#000 88%,transparent 100%);
  }
}
@media (prefers-reduced-motion:reduce){
  .trust-track{animation:none}
  .trust-track .pill[aria-hidden="true"]{display:none}
  .trust-strip{overflow-x:auto;mask-image:none;-webkit-mask-image:none}
}

/* ============================================================
   HEADER - sticky, hides on scroll-down (Gentle behaviour)
   ============================================================ */
/* deliberately NOT sticky: this page is embedded under osint.industries'
   own sticky header, and two stacked sticky bars fight each other. */
.hdr{
  position:relative;z-index:2;
  padding-block:48px 30px;
  background:var(--ground);
}
.hdr .n1{grid-column:7/10}
.hdr .n2{grid-column:10/12}
.hdr .n3{grid-column:12/13;justify-content:center}
@media (max-width:900px){
  .hdr.g{display:flex;align-items:center;justify-content:flex-end;gap:var(--gutter);padding-block:28px 16px}
  .hdr .n1{display:none}
  .hdr .n2,.hdr .n3{flex:0 0 auto;width:auto}
  .hdr .pill{white-space:nowrap}
}

/* ============================================================
   TILE - Gentle "tablet": 18px pad, 15px radius, surface fill
   ============================================================ */
.tile{
  display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
  width:100%;text-align:left;
  padding:18px;
  border-radius:15px;
  background:var(--surface);
  color:var(--ink);
  font-size:var(--f-s);
  line-height:1.25;
  letter-spacing:-0.005em;
  border:1px solid transparent;
  transition:background .45s var(--e1),border-color .45s var(--e1),color .45s var(--e1);
}
.tile--static{cursor:default}
button.tile:hover{background:var(--surface-hi)}
.tile .idx{
  flex:none;
  font-family:var(--mono);
  font-size:var(--f-xs);
  letter-spacing:0.04em;
  color:var(--muted);
  opacity:0;
  transition:opacity .3s var(--e2),color .3s var(--e2);
  font-variant-numeric:tabular-nums;
}
button.tile:hover .idx{opacity:1}
.tile.on{background:var(--accent-wash);border-color:var(--accent-line)}
.tile.on .idx,.tile.on:hover .idx{opacity:1;color:var(--accent)}

/* ============================================================
   COURSE HEADER
   ============================================================ */
/* set --site-header to the host header's height when embedding, so the
   pinned course names clear it instead of sliding underneath */
.course-head{display:flex;flex-direction:column;gap:10px;position:sticky;
  top:calc(var(--site-header, 0px) + 28px)}
@media (max-width:900px){.course-head{position:static}}
.assess{
  display:flex;flex-wrap:wrap;gap:8px;align-items:baseline;
  padding-top:2px;
}
/* dims the other two courses once modules are being picked from one -
   syllabuses build within a single course, they don't mix across them */
.course{transition:opacity .35s var(--e1)}
.course.is-other{opacity:.4}

/* ============================================================
   STATS
   ============================================================ */
.stat{grid-column:span 3;display:flex;flex-direction:column;gap:6px}
.stat .n{font-size:var(--f-xl);line-height:1.1;letter-spacing:-0.015em;font-variant-numeric:tabular-nums}
@media (max-width:900px){.stat{grid-column:span 6}}

/* ============================================================
   FEATURED CASE - full-width link row
   ============================================================ */
.case{
  grid-column:1/13;
  display:flex;align-items:center;justify-content:space-between;gap:24px;
  padding:26px;border-radius:15px;
  background:var(--surface);
  transition:background .45s var(--e1);
}
.case:hover{background:var(--accent-wash)}
.case .arw{transition:transform .45s var(--e1)}
.case:hover .arw{transform:translateX(6px)}
@media (max-width:640px){.case{flex-direction:column;align-items:flex-start;gap:14px}}

/* ============================================================
   TESTIMONIAL - pull quote beside a portrait interview clip
   ============================================================ */
.tq-quotes{grid-column:1/8;display:flex;flex-direction:column;gap:56px}
.tq-item{display:flex;flex-direction:column;gap:18px}
.tq-by{display:flex;flex-direction:column;gap:5px}
.tq-video{grid-column:10/13;display:flex;flex-direction:column;gap:12px}
.tq-player{
  width:100%;aspect-ratio:9/16;display:block;
  border-radius:15px;background:var(--surface);
  /* the clip carries burnt-in captions, so it must never be cropped */
  object-fit:contain;
}
@media (max-width:900px){
  .tq-quotes{grid-column:1/13;margin-bottom:48px;gap:44px}
  .tq-video{grid-column:1/13;max-width:330px}
}

/* ============================================================
   TRAINING LOG STRIP - compact horizontal scroller
   ============================================================ */
.log-head{
  display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  margin-bottom:18px;
}
.log-scroll{
  display:flex;gap:var(--gutter);
  overflow-x:auto;
  overflow-y:hidden;
  scroll-snap-type:x proximity;
  scroll-padding-left:var(--edge);
  padding-bottom:6px;
  margin-inline:calc(var(--edge) * -1);
  padding-inline:var(--edge);
  -webkit-overflow-scrolling:touch;
  scrollbar-width:thin;
  scrollbar-color:var(--line) transparent;
}
.log-scroll:focus-visible{outline:2px solid var(--accent);outline-offset:4px;border-radius:15px}
.log-scroll::-webkit-scrollbar{height:6px}
.log-scroll::-webkit-scrollbar-track{background:transparent}
.log-scroll::-webkit-scrollbar-thumb{background:var(--line);border-radius:10px}
.log-card{
  flex:0 0 auto;
  width:min(72vw,240px);
  scroll-snap-align:start;
  border-radius:15px;
  overflow:hidden;
  background:var(--surface);
  display:flex;flex-direction:column;
  transition:transform .45s var(--e1),background .45s var(--e1);
}
.log-card:hover{background:var(--surface-hi);transform:translateY(-3px)}
.log-card img{
  width:100%;height:120px;object-fit:cover;display:block;
  background:var(--surface-hi);
}
.log-meta{
  display:flex;flex-direction:column;gap:6px;
  padding:14px;
}
.log-meta .t-s{
  line-height:1.3;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}

/* ============================================================
   MANIFESTO - full-bleed colour block, pinned while it is read.
   The section is taller than the viewport; the inner panel sticks to the
   top, so scrolling moves the page past a held statement and drives the
   words lighting up one after another.
   ============================================================ */
.manifesto{
  background:var(--block-bg);
  color:rgb(var(--block-fg-rgb));
  height:160vh;
  margin-bottom:var(--rhythm-lg);
}
.manifesto-pin{position:sticky;top:0;height:100vh;display:flex;align-items:center}
.manifesto-pin > .g{width:100%}
.mw{color:rgba(var(--block-fg-rgb),var(--a,1));transition:color .2s linear}
.mw--dim{color:rgba(var(--block-dim-rgb),var(--a,1))}
@media (max-width:900px){.manifesto{height:150vh}}
@media (prefers-reduced-motion:reduce){
  .manifesto{height:auto;margin-bottom:var(--rhythm)}
  .manifesto-pin{position:static;height:auto;padding-block:var(--rhythm)}
  .mw{color:rgb(var(--block-fg-rgb));transition:none}
  .mw--dim{color:rgb(var(--block-dim-rgb))}
}

/* ============================================================
   FAQ - native <details> rows wearing the tile component
   ============================================================ */
.faq{background:var(--surface);border-radius:15px;transition:background .45s var(--e1)}
.faq:hover{background:var(--surface-hi)}
.faq summary{
  display:flex;align-items:flex-start;justify-content:space-between;gap:20px;
  padding:18px;cursor:pointer;
  font-size:var(--f-s);line-height:1.25;letter-spacing:-0.005em;
  list-style:none;
}
/* the default disclosure triangle, removed in both engines */
.faq summary::-webkit-details-marker{display:none}
.faq summary::marker{content:""}
.faq summary:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:15px}
.faq .sign{flex:none;font-family:var(--mono);font-size:var(--f-mono);line-height:1.5;color:var(--muted)}
.faq .sign::after{content:"+"}
.faq[open] .sign{color:var(--accent)}
.faq[open] .sign::after{content:"\2212"}
.faq-a{display:flex;flex-direction:column;gap:14px;padding:0 50px 18px 18px}
@media (max-width:900px){.faq-a{padding-right:18px}}

/* ============================================================
   COPY-EMAIL - Gentle's "email + Copy" affordance
   ============================================================ */
.copy{
  display:inline-flex;align-items:center;gap:12px;
  padding:8px 12px;border-radius:40px;
  background:var(--surface);
  font-family:var(--mono);font-size:var(--f-mono);letter-spacing:0.02em;
  transition:background .45s var(--e1);
}
.copy:hover{background:var(--accent-wash)}
.copy .cta{color:var(--label);text-transform:uppercase;letter-spacing:0.06em;font-size:var(--f-xs)}
.copy.done .cta{color:var(--accent)}

/* ============================================================
   SYLLABUS BAR
   ============================================================ */
.bar{
  position:fixed;left:0;right:0;bottom:0;z-index:60;
  padding:0 var(--edge) 18px;
  pointer-events:none;
  transform:translateY(140%);
  transition:transform .6s var(--e1);
}
.bar.up{transform:none}
.bar-in{
  pointer-events:auto;
  grid-column:1/13;
  display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;
  padding:10px 10px 10px 20px;
  border-radius:40px;
  background:var(--ink);
  color:var(--ground);
  box-shadow:var(--shadow);
}
.bar-read{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;font-family:var(--mono);font-size:var(--f-mono);letter-spacing:0.03em}
.bar-read .sep{color:var(--muted)}
.bar-read b{font-weight:500;font-variant-numeric:tabular-nums}
.bar-acts{display:flex;gap:8px;align-items:center}
.bar-acts .pill{background:rgba(255,255,255,.12);color:var(--ground)}
.bar-acts .pill:hover{background:rgba(255,255,255,.22)}
.bar-acts .pill--solid{background:var(--accent);color:var(--on-accent)}
.bar-acts .pill--solid:hover{background:var(--accent);filter:brightness(1.08)}

/* The syllabus bar is fixed over the end of the page and wraps to two rows on
   narrow screens. The removed footer used to carry the clearance; without it the
   last CTA sat directly under the bar, so reserve the room explicitly.        */
@media (max-width:900px){ main{padding-bottom:72px} }

/* ============================================================
   REVEAL
   ============================================================ */
/* Content is visible by default; the hidden state is only applied once JS
   has confirmed it can reveal it again. No JS, no observer, no blank page. */
html.anim .rv{opacity:0;transform:translateY(16px);transition:opacity .9s var(--e1),transform .9s var(--e1)}
html.anim .rv.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  html.anim .rv{opacity:1;transform:none;transition:none}
  *{transition-duration:.01ms !important;animation-duration:.01ms !important}
  .hdr{transition:none}
}
