/* =========================================================================
   The Validation Summit 26 — landing page stylesheet
   Source of truth: meetings/08.25.2026/assets/summitlpblueprint_15_32.html
   (Beyza's approved blueprint, moved into the Shield theme 26 Aug 2026).
   The block below is a 1:1 copy of the blueprint CSS; keep it in sync with
   design revisions rather than editing selectively. Shield's main.css is NOT
   loaded by this template, so these tokens live alone on the page.
   ========================================================================= */
:root{
  --navy:#EEF5FD; --fuchsia:#F21668;   /* navy var now carries the paper colour */
  --ink:#002B45; --dim:rgba(0,43,69,.80);
  --line:rgba(0,43,69,.58); --soft:rgba(0,43,69,.15);
  --display:"Red Hat Display",system-ui,sans-serif;
  --body:"Inter",system-ui,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,monospace;

  /* ---- one composition scale -------------------------------------------
     Every size below used to key off vw alone, so type froze at its cap from
     1366px wide upward while the viewport HEIGHT ran from 768 to 1440. The
     result: on a 13" screen the plate ate 52% of the frame and sat on top of
     the drawing, and on a 27" monitor the same plate was a small island.
     In this layout one panel IS one screen, so height is the binding
     dimension. --s is the effective design height; width is divided in only
     to stop an ultrawide from over-scaling. Bounds keep a 768px-tall laptop
     legible and a 1440px-tall monitor from turning cartoonish. Every ratio
     below is expressed against 900, so --s:900 reproduces today's 13" look
     exactly and every other screen keeps the same proportions. */
  --s:clamp(680px, min(100vh, calc(100vw / 1.55)), 1440px);

  /* ---- one button spec -------------------------------------------------
     Taken from the registration form's submit button, which is the reference:
     17px / 14px 30px at the 900 design size. Every button on the page reads
     these tokens, so they cannot drift apart later. Capped, because a button is
     a target to hit, not a headline — this is also what brings the banner CTA
     down from 29px. */
  --btn-size:clamp(15px, calc(var(--s)*.0189), 22px);
  --btn-pad-y:clamp(12px, calc(var(--s)*.0156), 18px);
  --btn-pad-x:clamp(24px, calc(var(--s)*.0333), 38px);
}
html{scroll-snap-type:y mandatory;scroll-behavior:smooth}
*{box-sizing:border-box}
body{margin:0;background:var(--navy);color:var(--ink);font-family:var(--body);
  -webkit-font-smoothing:antialiased}

#stage{position:fixed;inset:0;overflow:hidden;z-index:1}
#grid{position:absolute;top:0;left:0;pointer-events:none;will-change:transform;
  background-color:rgba(0,43,69,.36);
  -webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='66' height='66'%3E%3Cg stroke='%23000' stroke-width='1.1' stroke-dasharray='6 5'%3E%3Cline x1='0' y1='0.5' x2='66' y2='0.5'/%3E%3Cline x1='0.5' y1='0' x2='0.5' y2='66'/%3E%3C/g%3E%3C/svg%3E");
  mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='66' height='66'%3E%3Cg stroke='%23000' stroke-width='1.1' stroke-dasharray='6 5'%3E%3Cline x1='0' y1='0.5' x2='66' y2='0.5'/%3E%3Cline x1='0.5' y1='0' x2='0.5' y2='66'/%3E%3C/g%3E%3C/svg%3E");
  -webkit-mask-size:66px 66px;mask-size:66px 66px;
  -webkit-mask-repeat:repeat;mask-repeat:repeat}
#vig{position:absolute;inset:0;pointer-events:none;z-index:1;
  background:radial-gradient(122% 86% at 50% 46%,transparent 52%,rgba(0,43,69,.10) 100%)}

#doodle{position:absolute;top:0;left:0;pointer-events:none;z-index:1;overflow:visible}
/* dark separation so line work never merges into the grid */
#doodle{}
#doodle text{font-family:var(--mono);fill:#002B45;letter-spacing:.1em;
  text-transform:uppercase;font-weight:500;
  paint-order:stroke fill;stroke:#EEF5FD;stroke-width:4px;stroke-linejoin:round}
#doodle .ln{stroke:rgba(0,43,69,.68);fill:none;stroke-width:2.2}
#doodle .ln-dim{stroke:rgba(0,43,69,.68);fill:none;stroke-width:2.2}
#doodle .ln-hid{stroke:rgba(0,43,69,.5);fill:none;stroke-width:2;stroke-dasharray:10 7}
#doodle .ln-ctr{stroke:rgba(0,43,69,.45);fill:none;stroke-width:2;stroke-dasharray:20 6 5 6}
#doodle .pk{stroke:var(--fuchsia);fill:none;stroke-width:2.8;opacity:1}
#doodle .pk-t{fill:var(--fuchsia);stroke:#EEF5FD;stroke-width:4px;paint-order:stroke fill}
#doodle .pk-ln{stroke:var(--fuchsia);fill:none;stroke-width:2.2}
#doodle .fillnavy{fill:var(--navy)}
#doodle .strike{stroke:var(--fuchsia);stroke-width:3;opacity:1}
/* hand layer: scrawled on top of the print */
#doodle .h1{stroke:var(--fuchsia);fill:none;stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round}
#doodle .h2{stroke:var(--fuchsia);fill:none;stroke-width:2;opacity:.66;
  stroke-linecap:round;stroke-linejoin:round}
#doodle .hw{fill:var(--fuchsia);stroke:#EEF5FD;stroke-width:4.5px;paint-order:stroke fill;
  font-family:"Caveat",cursive;font-weight:700;text-transform:none;letter-spacing:0}

#canvas{position:absolute;top:0;left:0;will-change:transform;z-index:5}
#route{position:absolute;top:0;left:0;pointer-events:none;z-index:2;overflow:visible;
}
#route .main{fill:none;stroke:rgba(0,43,69,.62);stroke-width:2.4}
#route .spur{fill:none;stroke:var(--fuchsia);stroke-width:2.6;stroke-dasharray:9 7}
#route .arrow{fill:rgba(0,43,69,.72)}
#route .sta{fill:#FFFFFF;stroke:rgba(0,43,69,.62);stroke-width:2.4}
#route .sta.on{fill:var(--fuchsia);stroke:var(--fuchsia)}
#route .cross{stroke:rgba(0,43,69,.6);stroke-width:1.8}

.panel{position:absolute;padding:calc(var(--s)*.0578) clamp(26px,5vw,calc(var(--s)*.0822));
  display:flex;flex-direction:column;justify-content:center;z-index:4}
/* margin-bottom also keeps the plate clear of the readout in the bottom-left,
   which is z-index 8 and was drawing straight over panel copy on 13" screens */
.panel .inner{max-width:calc(var(--s)*.689);margin-bottom:calc(var(--s)*.155);position:relative;
  max-height:100%;min-height:0;
  background:#FFFFFF;border:1px solid rgba(0,43,69,.30);
  padding:calc(var(--s)*.0378) calc(var(--s)*.0422) calc(var(--s)*.0422)}
.panel .inner::before,.panel .inner::after{content:"";position:absolute;width:11px;height:11px;
  border:1px solid var(--fuchsia);z-index:2}
.panel .inner::before{top:-1px;left:-1px;border-right:0;border-bottom:0}
.panel .inner::after{bottom:-1px;right:-1px;border-left:0;border-top:0}
.panel.wide .inner{max-width:calc(var(--s)*1.0667);margin-bottom:0;
  padding:calc(var(--s)*.0289) calc(var(--s)*.0333) calc(var(--s)*.0333)}

/* The speaker grid is the one plate with no bottom margin, so its lower-left
   card landed exactly under the readout — a whole speaker was hidden behind it
   at every screen size. Start this plate to the right of the readout instead. */
.panel.wide{padding-left:max(calc(var(--s)*.0822),calc(var(--s)*.305),284px)}

/* The three-up portrait column reaches into the same corner; nudging the row up
   clears the last caption without touching the plate's width. */
.panel.withinsert{padding-bottom:calc(var(--s)*.145)}

/* banner station: plate centred in the frame */
.panel.center{align-items:center}
.panel.center .inner{max-width:calc(var(--s)*.733);margin-bottom:0}

#mottle,#grain{position:fixed;inset:0;pointer-events:none}
#mottle{display:none;z-index:6;mix-blend-mode:soft-light;background:
  radial-gradient(38% 44% at 18% 22%,rgba(255,255,255,.10),transparent 70%),
  radial-gradient(46% 40% at 82% 30%,rgba(0,0,0,.13),transparent 72%),
  radial-gradient(52% 48% at 68% 84%,rgba(255,255,255,.07),transparent 70%),
  radial-gradient(40% 36% at 8% 88%,rgba(0,0,0,.11),transparent 72%)}
#grain{display:none;z-index:6;mix-blend-mode:overlay;opacity:.18;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:180px 180px}

#frame{position:fixed;inset:22px;border:1px solid var(--line);z-index:7;pointer-events:none}
#frame b{position:absolute;inset:6px;border:1px solid var(--line);opacity:.34}
#frame i{position:absolute;width:14px;height:14px;border:0 solid var(--fuchsia)}
#frame i:nth-child(2){top:-1px;left:-1px;border-top-width:2px;border-left-width:2px}
#frame i:nth-child(3){top:-1px;right:-1px;border-top-width:2px;border-right-width:2px}
#frame i:nth-child(4){bottom:-1px;left:-1px;border-bottom-width:2px;border-left-width:2px}
#frame i:nth-child(5){bottom:-1px;right:-1px;border-bottom-width:2px;border-right-width:2px}

/* the readout needs its own plate: without one the dashed grid runs straight
   through the type, and in this drawing's language a line through a word means
   the word has been cancelled */
/* chrome scales too, or it eats a quarter of a 768px-tall screen while looking
   like a stamp on a 27" monitor. max() keeps a legibility floor. */
#hud{position:fixed;left:calc(var(--s)*.04);bottom:calc(var(--s)*.04);z-index:8;
  font-family:var(--mono);font-size:max(10px,calc(var(--s)*.0122));
  letter-spacing:.13em;text-transform:uppercase;color:rgba(0,43,69,.74);
  background:#FFFFFF;border:1px solid rgba(0,43,69,.30);
  padding:calc(var(--s)*.0122) calc(var(--s)*.0144) calc(var(--s)*.0144);
  max-width:calc(var(--s)*.235)}
#hud .dirn{color:var(--fuchsia);display:block;margin-bottom:calc(var(--s)*.0056);font-weight:500}
#hud .staname{display:block;margin-bottom:calc(var(--s)*.01);color:var(--ink)}
#hud .idxlab{display:block;font-size:max(8.5px,calc(var(--s)*.01));letter-spacing:.14em;
  color:rgba(0,43,69,.55);margin-bottom:calc(var(--s)*.0067)}
#mini{border:1px solid var(--line);background:rgba(255,255,255,.78);display:inline-block}
#mini svg{display:block}
#mini .mline{stroke:var(--line);stroke-width:1;fill:none}
#mini .mspur{stroke:var(--fuchsia);stroke-width:1;fill:none;stroke-dasharray:3 3}
#mini .mdot{fill:none;stroke:var(--line);stroke-width:1.2}
#mini .mdot.on{fill:var(--fuchsia);stroke:var(--fuchsia)}
/* the hit circle is the hover surface, so it can show state without needing a
   sibling selector back to the dot */
#mini .mhit:hover{fill:rgba(242,22,104,.18)}
#mini .mhit:focus{outline:none;fill:rgba(242,22,104,.22)}
#mini .mhit:focus-visible{fill:rgba(242,22,104,.24);stroke:var(--fuchsia);stroke-width:1.5}

/* station navigation */
#nav{position:fixed;right:22px;bottom:22px;z-index:9;display:flex;align-items:stretch;
  font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase}
#nav button{all:unset;cursor:pointer;width:40px;height:38px;display:grid;place-items:center;
  color:var(--ink);border:1px solid rgba(0,43,69,.4);background:rgba(255,255,255,.9);
  font-size:15px;transition:background .18s ease,color .18s ease}
#nav button:hover{background:var(--fuchsia);border-color:var(--fuchsia);color:#fff}
#nav button[disabled]{opacity:.34;cursor:default}
#nav button[disabled]:hover{background:rgba(255,255,255,.9);border-color:rgba(0,43,69,.4);color:var(--ink)}
/* all:unset stripped the focus ring, so a keyboard user had nothing to follow */
#nav button:focus-visible{outline:2px solid var(--fuchsia);outline-offset:2px}
#nav .count{display:grid;place-items:center;padding:0 14px;color:var(--ink);
  border:1px solid rgba(0,43,69,.4);border-left:0;border-right:0;background:rgba(255,255,255,.9)}
#mini svg{cursor:pointer}
#mini .mhit{fill:transparent;cursor:pointer}

/* The four corners are taken — readout bottom-left, stations bottom-right,
   compass top-right — so the action sits bottom-centre, in the same band as the
   other instruments but solid rather than plated, because it is the one thing
   here meant to be clicked rather than read. */
#stickyCta{position:fixed;left:50%;bottom:calc(var(--s)*.04);z-index:9;
  transform:translate(-50%,14px);opacity:0;pointer-events:none;
  box-shadow:0 10px 30px rgba(0,43,69,.20);
  transition:opacity .22s ease,transform .22s ease}
#stickyCta.on{opacity:1;transform:translate(-50%,0);pointer-events:auto}

#compass{position:fixed;right:23px;top:23px;z-index:8;font-family:var(--mono);font-size:11px;
  letter-spacing:.16em;color:var(--dim);text-align:center;line-height:1.1}
#compass b{display:block;color:var(--fuchsia);font-size:11px;margin-bottom:2px}
#compass s{display:block;width:1px;height:24px;background:var(--line);margin:3px auto 0;text-decoration:none}

/* every size keyed to --s, ratios taken against 900 so the 13" render is
   unchanged and every other screen holds the same proportion */
.eyebrow{font-family:var(--mono);font-size:calc(var(--s)*.0139);letter-spacing:.2em;
  text-transform:uppercase;color:var(--fuchsia);margin:0 0 calc(var(--s)*.0222);font-weight:500}
h1{font-family:var(--display);font-weight:900;font-size:calc(var(--s)*.0956);line-height:.95;
  letter-spacing:-.03em;margin:0 0 calc(var(--s)*.0178);color:var(--ink)}
h1 em{font-style:normal;color:var(--fuchsia)}
.sub{font-family:var(--display);font-weight:700;font-size:calc(var(--s)*.0333);line-height:1.22;
  letter-spacing:-.01em;color:var(--ink);margin:0 0 calc(var(--s)*.0311);max-width:24em}
h2{font-family:var(--display);font-weight:700;font-size:calc(var(--s)*.0511);line-height:1.07;
  letter-spacing:-.02em;margin:0 0 calc(var(--s)*.0133);color:var(--ink)}
h3{font-family:var(--display);font-weight:700;font-size:calc(var(--s)*.0422);line-height:1.1;
  letter-spacing:-.015em;margin:0 0 calc(var(--s)*.0122);color:var(--ink)}
.lede{font-size:calc(var(--s)*.0222);color:var(--ink);max-width:33em;
  margin:0 0 calc(var(--s)*.0267);line-height:1.55}
.who{color:#F21668;font-weight:500;font-size:calc(var(--s)*.0189);margin:0 0 calc(var(--s)*.0167)}
p.txt{color:rgba(0,43,69,.82);font-size:calc(var(--s)*.0183);line-height:1.62;max-width:34em;margin:0}
.time{font-family:var(--mono);font-size:calc(var(--s)*.0144);letter-spacing:.14em;
  text-transform:uppercase;color:var(--fuchsia);margin:0 0 calc(var(--s)*.0167);
  display:flex;align-items:center;gap:calc(var(--s)*.0133);font-weight:500}
.time s{width:calc(var(--s)*.0333);height:1px;background:var(--fuchsia);
  text-decoration:none;display:block}

.meta{display:flex;gap:calc(var(--s)*.0333);flex-wrap:wrap;border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);padding:calc(var(--s)*.0156) 0;margin:0 0 calc(var(--s)*.0311)}
.meta div{font-family:var(--mono);font-size:calc(var(--s)*.0128);letter-spacing:.1em;
  text-transform:uppercase;color:rgba(0,43,69,.72)}
.meta b{display:block;font-family:var(--display);font-weight:700;font-size:calc(var(--s)*.0194);
  letter-spacing:0;text-transform:none;color:var(--ink);margin-top:calc(var(--s)*.0067)}

.cta{display:inline-block;font-family:var(--display);font-weight:900;
  font-size:var(--btn-size);color:#EEF5FD;text-decoration:none;background:var(--ink);
  border:1px solid var(--ink);border-radius:0;
  padding:var(--btn-pad-y) var(--btn-pad-x);
  transition:background .16s ease,border-color .16s ease}
/* the form button's hover is a colour change with no lift, so this one matches */
.cta:hover{background:var(--fuchsia);border-color:var(--fuchsia)}
.fine{font-family:var(--mono);font-size:calc(var(--s)*.0128);letter-spacing:.12em;
  text-transform:uppercase;color:rgba(0,43,69,.68);margin-top:calc(var(--s)*.02)}
.hint{display:flex;align-items:center;gap:calc(var(--s)*.0133);font-family:var(--mono);
  font-size:calc(var(--s)*.0133);letter-spacing:.16em;text-transform:uppercase;
  color:var(--fuchsia);margin-top:calc(var(--s)*.02)}
/* The arrow points east because that is where the drawing goes, and the first
   leg out of Sta. 01 genuinely runs east. It only contradicted the copy while
   the copy named a gesture; "travel the blueprint" names the route instead. */
.hint em{font-style:normal;width:calc(var(--s)*.0444);height:1px;background:var(--fuchsia);
  position:relative}
/* mobile-only: on desktop these four figures are drawn in the sheet's annotation
   layer, so the markup stays hidden there and is switched on in the phone block */
.mkeys,.mloop{display:none}
.hint em::after{content:"";position:absolute;right:0;top:calc(var(--s)*-.0033);
  border-left:calc(var(--s)*.0067) solid var(--fuchsia);
  border-top:calc(var(--s)*.0039) solid transparent;
  border-bottom:calc(var(--s)*.0039) solid transparent}

/* The demo session's day, stated as beats rather than one long paragraph. The
   time is the anchor, so it gets the mono/accent treatment and its own column. */
.daylist{list-style:none;margin:calc(var(--s)*.0189) 0 0;padding:0;display:grid;
  gap:calc(var(--s)*.0122)}
.daylist li{display:grid;grid-template-columns:auto 1fr;
  gap:calc(var(--s)*.0167);align-items:baseline}
.daylist b{font-family:var(--mono);font-size:calc(var(--s)*.0144);letter-spacing:.1em;
  color:var(--fuchsia);font-weight:500;white-space:nowrap}
.daylist span{font-size:calc(var(--s)*.0172);line-height:1.5;color:rgba(0,43,69,.82)}

.stamp{display:inline-block;font-family:var(--mono);font-size:calc(var(--s)*.0128);
  letter-spacing:.18em;text-transform:uppercase;color:var(--fuchsia);
  border:1px solid var(--fuchsia);padding:calc(var(--s)*.0044) calc(var(--s)*.0111);
  transform:rotate(-2.2deg);margin-bottom:calc(var(--s)*.0178)}

/* ---- Sta. 07 is not part of the summit ----------------------------------
   It runs days later and takes its own registration, so it stops wearing the
   same white plate as the seven panels that ARE the summit. The route already
   reaches it by a dashed fuchsia spur rather than the solid main line; this
   makes the panel say what the drawing was already saying.
   Brand fuchsia throughout, per the palette. Note it measures 3.6:1 against this
   navy, so the small mono labels below sit under the 4.5:1 AA floor for their
   size — the same call the page already makes on white, where brand fuchsia
   reads 4.1:1. The CTA hover gains from it: white on #F21668 is 4.1:1 against
   3.2:1 on the lighter tint. */
.panel.offline .inner{background:var(--ink);border-color:var(--ink)}
.panel.offline .inner::before,.panel.offline .inner::after{border-color:var(--fuchsia)}
.panel.offline h3{color:#EEF5FD}
.panel.offline p.txt{color:rgba(238,245,253,.84)}
.panel.offline .eyebrow{color:var(--fuchsia)}
.panel.offline .stamp{color:var(--fuchsia);border-color:var(--fuchsia)}
.panel.offline .fine{color:rgba(238,245,253,.72)}
/* The readout is pinned bottom-left and this plate is left-aligned and tall, so
   the two met exactly over the invitation CTA. No insert here means there is room
   to start the plate to the right of the readout instead. The inset tracks the
   readout's own scale (left .04 + max-width .235 + breathing .03) rather than a
   fixed 284px, which stopped clearing it once the readout grew with --s. */
.panel.offline{padding-left:max(calc(var(--s)*.0822),calc(var(--s)*.305),284px)}
/* the main CTA is ink on paper, which would vanish here, so it inverts */
.panel.offline .cta{background:#EEF5FD;border-color:#EEF5FD;color:var(--ink);
  margin-top:calc(var(--s)*.0067)}
/* pure white, not the page's paper tint: #EEF5FD over this pink lands at
   2.87:1 and fails even the large-text floor, while #FFF clears it */
.panel.offline .cta:hover{background:var(--fuchsia);border-color:var(--fuchsia);color:#FFFFFF}

/* speaker grid, photo placeholders drawn as drafting voids */
.people{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:calc(var(--s)*.0156) calc(var(--s)*.0244);margin-top:calc(var(--s)*.0178)}
.person .ph{height:calc(var(--s)*.1911);border:1px solid var(--line);position:relative;
  margin-bottom:calc(var(--s)*.0111);overflow:hidden;
  background-image:
    linear-gradient(to top right,transparent calc(50% - .6px),var(--soft) calc(50% - .6px),var(--soft) calc(50% + .6px),transparent calc(50% + .6px)),
    linear-gradient(to bottom right,transparent calc(50% - .6px),var(--soft) calc(50% - .6px),var(--soft) calc(50% + .6px),transparent calc(50% + .6px))}
.person .ph{background:#FFFFFF}
.person .ph > img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:grayscale(1) contrast(1.06);
  mix-blend-mode:multiply;
  transition:filter .4s ease,mix-blend-mode .4s ease,opacity .4s ease}
.person .ph::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(168deg,rgba(0,43,69,.14) 0%,rgba(0,43,69,.05) 55%,rgba(242,22,104,.12) 100%);
  mix-blend-mode:multiply;opacity:1;transition:opacity .4s ease}
.person:hover .ph > img{filter:grayscale(.1) contrast(1.02);mix-blend-mode:normal}
.person:hover .ph::after{opacity:.35}
.person .ph .tag{position:absolute;left:calc(var(--s)*.0078);bottom:calc(var(--s)*.0067);z-index:2;
  font-family:var(--mono);font-size:calc(var(--s)*.01);letter-spacing:.14em;
  text-transform:uppercase;color:rgba(0,43,69,.7)}
.person .ph .mk{position:absolute;width:10px;height:10px;border:1px solid var(--fuchsia);z-index:2}
.person .ph .mk.tl{top:5px;left:5px;border-right:0;border-bottom:0}
.person .ph .mk.br{bottom:5px;right:5px;border-left:0;border-top:0}

/* portrait insert: its own drafted frame, plate laid over it */
.panel.withinsert{flex-direction:row;align-items:center;justify-content:flex-start;gap:0}
.panel.withinsert .inner{position:relative;z-index:4;margin-left:calc(var(--s)*-.0378);
  padding:calc(var(--s)*.0378) calc(var(--s)*.0422) calc(var(--s)*.0422) calc(var(--s)*.0711);
  max-width:calc(var(--s)*.733)}
.insert{position:relative;z-index:3;flex:0 0 auto;background:#FFFFFF;
  border:1px solid rgba(0,43,69,.30);width:calc(var(--s)*.2933)}
.insert .ph{position:relative;overflow:hidden;background:#FFFFFF;
  height:calc(var(--s)*.3533)}
.insert.three .ph{height:calc(var(--s)*.1378)}
.insert.three .ph + .cap + .ph{border-top:1px solid rgba(0,43,69,.18)}
/* two-up: the demo is walked by a pair, so the frame sits between the single
   portrait and the three-up panel */
.insert.two .ph{height:calc(var(--s)*.1911)}
.insert.two .ph + .cap + .ph{border-top:1px solid rgba(0,43,69,.18)}
.insert.two .cap{padding:calc(var(--s)*.0078) calc(var(--s)*.0467) calc(var(--s)*.0078) calc(var(--s)*.0122)}
/* A placeholder stated in drafting language: an unplaced view is crossed
   through, not left as an empty white box. */
.insert .ph.void{background:#FFFFFF;background-image:
  linear-gradient(to top right,transparent calc(50% - .5px),var(--soft) calc(50% - .5px),var(--soft) calc(50% + .5px),transparent calc(50% + .5px)),
  linear-gradient(to bottom right,transparent calc(50% - .5px),var(--soft) calc(50% - .5px),var(--soft) calc(50% + .5px),transparent calc(50% + .5px))}
.insert .ph.void::after{display:none}
/* left-aligned like every other label inside a photo box, and because the plate
   overlaps the right of the frame a centred label would read as off-centre */
.insert .ph .vlab{position:absolute;left:calc(var(--s)*.0122);bottom:calc(var(--s)*.0078);z-index:2;
  font-family:var(--mono);font-size:calc(var(--s)*.0094);letter-spacing:.14em;
  text-transform:uppercase;color:rgba(0,43,69,.52)}
.insert .ph img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:center 22%;filter:grayscale(1) contrast(1.06);mix-blend-mode:multiply;
  transition:filter .4s ease,mix-blend-mode .4s ease}
.insert .ph::after{content:"";position:absolute;inset:0;pointer-events:none;mix-blend-mode:multiply;
  background:linear-gradient(168deg,rgba(0,43,69,.14),rgba(242,22,104,.12))}
.insert .ph:hover img{filter:grayscale(.06) contrast(1.02);mix-blend-mode:normal}
.insert .mk{position:absolute;width:10px;height:10px;border:1px solid var(--fuchsia);z-index:2}
.insert .mk.tl{top:5px;left:5px;border-right:0;border-bottom:0}
.insert .mk.br{bottom:5px;right:5px;border-left:0;border-top:0}
.insert .cap{font-family:var(--mono);font-size:calc(var(--s)*.0106);letter-spacing:.13em;
  text-transform:uppercase;color:rgba(0,43,69,.6);
  padding:calc(var(--s)*.0089) calc(var(--s)*.0467) calc(var(--s)*.0089) calc(var(--s)*.0122);
  border-top:1px solid rgba(0,43,69,.30);display:flex;flex-direction:column;gap:calc(var(--s)*.0022)}
.insert .cap b{color:var(--ink);font-weight:500;font-size:calc(var(--s)*.0117)}
.insert.three .cap{padding:calc(var(--s)*.0067) calc(var(--s)*.0467) calc(var(--s)*.0067) calc(var(--s)*.0122)}
/* registration frame, drafted like the portrait inserts */
.panel.withform{flex-direction:row;align-items:center;justify-content:flex-start;
  gap:calc(var(--s)*.0489)}
.panel.withform .inner{max-width:calc(var(--s)*.5778);margin-bottom:0}
.formframe{position:relative;flex:0 0 auto;background:#FFFFFF;
  border:1px solid rgba(0,43,69,.30);width:calc(var(--s)*.4578);
  max-height:78vh;overflow:auto}
.formframe .fhead{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:rgba(0,43,69,.62);padding:11px 14px;
  border-bottom:1px solid rgba(0,43,69,.30);display:flex;justify-content:space-between;gap:10px}
.formframe .fhead b{color:var(--ink);font-weight:500}
.formframe .fmk{position:absolute;width:10px;height:10px;border:1px solid var(--fuchsia);z-index:2}
.formframe .fmk.tl{top:5px;left:5px;border-right:0;border-bottom:0}
.formframe .fmk.br{bottom:5px;right:5px;border-left:0;border-top:0}
.formframe .fbody{padding:16px 18px 20px}
.formframe .floading{font-family:var(--mono);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;color:rgba(0,43,69,.5);margin:0 0 14px}
.formframe .fallbackcta{width:100%;text-align:center}

/* HubSpot form, forced into the drawing's language */
#summitForm form{margin:0 !important}
#summitForm .hs-form-field{margin-bottom:13px !important}
#summitForm label{font-family:var(--mono) !important;
  font-size:clamp(10px,calc(var(--s)*.0111),12.5px) !important;
  letter-spacing:.13em !important;text-transform:uppercase !important;
  color:rgba(0,43,69,.72) !important;font-weight:500 !important;margin-bottom:5px !important;
  display:block !important}
#summitForm .hs-form-required{color:var(--fuchsia) !important;margin-left:3px}
/* the frame scales with --s, so the fields inside it do too, or the chevron ends
   up larger than the text it sits beside. Capped: this is a form to type in. */
#summitForm input[type=text],#summitForm input[type=email],#summitForm input[type=tel],
#summitForm input[type=number],#summitForm select,#summitForm textarea{
  width:100% !important;box-sizing:border-box !important;
  font-family:var(--body) !important;color:var(--ink) !important;
  font-size:clamp(14px,calc(var(--s)*.0161),18px) !important;
  background:#EEF5FD !important;border:1px solid rgba(0,43,69,.30) !important;
  border-radius:0 !important;box-shadow:none !important;
  padding:clamp(10px,calc(var(--s)*.0111),14px) clamp(12px,calc(var(--s)*.0133),17px) !important}
/* background-color, not the background shorthand: the shorthand reset the select's
   chevron to none on focus, so the arrow vanished the moment you clicked the field */
#summitForm input:focus,#summitForm select:focus,#summitForm textarea:focus{
  outline:none !important;border-color:var(--fuchsia) !important;background-color:#fff !important}

/* The native select arrow is drawn hard against the right edge, inside a 12px
   padding — cramped, and it is the OS widget rather than anything in this
   drawing's language. Replace it with a thin drafted chevron and give it room. */
#summitForm select:not([multiple]){
  -webkit-appearance:none !important;-moz-appearance:none !important;appearance:none !important;
  padding-right:clamp(38px,calc(var(--s)*.0455),52px) !important;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='9' viewBox='0 0 13 9'%3E%3Cpath d='M1.4 1.6 L6.5 6.9 L11.6 1.6' fill='none' stroke='%23002B45' stroke-opacity='.6' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") !important;
  background-repeat:no-repeat !important;
  background-position:right clamp(15px,calc(var(--s)*.0167),19px) center !important;
  background-size:clamp(12px,calc(var(--s)*.0139),15px) auto !important}
#summitForm select:not([multiple]):hover{background-color:#FFFFFF !important}
/* Firefox keeps a text-shadow on disabled options and an inner focus ring */
#summitForm select:not([multiple])::-ms-expand{display:none !important}
#summitForm .hs-error-msg,#summitForm .hs-error-msgs label{
  color:var(--fuchsia) !important;font-family:var(--body) !important;font-size:12px !important;
  letter-spacing:0 !important;text-transform:none !important}
#summitForm .hs-button{
  font-family:var(--display) !important;font-weight:900 !important;
  font-size:var(--btn-size) !important;
  color:#EEF5FD !important;background:var(--ink) !important;border:1px solid var(--ink) !important;
  border-radius:0 !important;padding:var(--btn-pad-y) var(--btn-pad-x) !important;width:100% !important;
  cursor:pointer !important;transition:background .16s ease,border-color .16s ease !important}
#summitForm .hs-button:hover{background:var(--fuchsia) !important;border-color:var(--fuchsia) !important}
/* ---- consent block ----------------------------------------------------
   The field-label rule above is deliberately mono/uppercase, but HubSpot uses
   <label> for consent checkboxes too, so it was shouting the legal copy in caps
   and letterspacing it. Consent text is body copy, and it is the one thing on
   the page a reader has to actually read before agreeing to it. */
#summitForm .legal-consent-container,#summitForm .hs-richtext{
  font-family:var(--body) !important;
  font-size:clamp(11.5px,calc(var(--s)*.0133),14px) !important;
  line-height:1.55 !important;letter-spacing:0 !important;text-transform:none !important;
  color:rgba(0,43,69,.7) !important}
/* HubSpot renders these as a <ul>, so they arrived with list bullets */
#summitForm .inputs-list{list-style:none !important;margin:0 !important;padding:0 !important}
#summitForm .inputs-list > li{margin:0 0 10px !important;padding:0 !important}
#summitForm .inputs-list > li:last-child{margin-bottom:0 !important}
#summitForm .hs-form-booleancheckbox-display,
#summitForm .hs-form-checkbox-display,
#summitForm .hs-form-radio-display{
  display:flex !important;align-items:flex-start !important;
  gap:clamp(8px,calc(var(--s)*.01),11px) !important;
  font-family:var(--body) !important;
  font-size:clamp(11.5px,calc(var(--s)*.0133),14px) !important;
  font-weight:400 !important;letter-spacing:0 !important;text-transform:none !important;
  line-height:1.5 !important;color:rgba(0,43,69,.78) !important;
  margin:0 !important;cursor:pointer}
#summitForm .hs-form-booleancheckbox-display > span,
#summitForm .hs-form-checkbox-display > span,
#summitForm .hs-form-radio-display > span{margin:0 !important}
#summitForm input[type=checkbox],#summitForm input[type=radio]{
  flex:0 0 auto;width:15px !important;height:15px !important;
  margin:2px 0 0 !important;accent-color:var(--fuchsia)}
#summitForm input[type=checkbox]:focus-visible,#summitForm input[type=radio]:focus-visible{
  outline:2px solid var(--fuchsia);outline-offset:2px}
#summitForm a{color:var(--fuchsia) !important;text-decoration:underline;
  text-underline-offset:2px}

/* ---- HubSpot's own grid ------------------------------------------------
   Its columns are floated percentage widths with an 8px right margin on the
   input wrapper, which pushed fields out of the frame. Flex instead. */
/* a fieldset draws a border by default; HubSpot's own stylesheet resets it, but
   relying on a third-party sheet for basic structure is how a form ends up with
   boxes around every row when that sheet is slow or blocked */
#summitForm fieldset{border:0 !important;margin:0 !important;padding:0 !important;
  max-width:none !important;width:100% !important}
#summitForm fieldset.form-columns-2,#summitForm fieldset.form-columns-3{
  display:flex !important;gap:clamp(10px,calc(var(--s)*.0144),16px) !important}
#summitForm fieldset > .hs-form-field{
  width:auto !important;flex:1 1 0 !important;float:none !important;padding:0 !important}
#summitForm .hs-form-field > .input{margin:0 !important}
#summitForm .hs_submit{margin-top:clamp(14px,calc(var(--s)*.0178),22px) !important}
#summitForm .actions{padding:0 !important;margin:0 !important}
#summitForm .submitted-message{font-family:var(--body) !important;color:var(--ink) !important}

@media (max-width:1040px){
  .panel.withform{flex-direction:column;align-items:flex-start;gap:16px}
  .panel.withform .inner{max-width:none}
  .formframe{width:100%;max-height:none}
  .panel.withinsert{flex-direction:column;align-items:flex-start}
  .panel.withinsert .inner{margin-left:0;padding:34px 38px 38px}
  .insert{display:none}
}

.person .org{display:flex;align-items:center;gap:calc(var(--s)*.01);
  margin-top:calc(var(--s)*.0078);min-height:calc(var(--s)*.02)}
.person .org img{height:calc(var(--s)*.0189);width:auto;max-width:calc(var(--s)*.1156);
  object-fit:contain;filter:brightness(0) saturate(0);opacity:.78}
.person .org em{display:none;font-style:normal;font-family:var(--mono);
  font-size:calc(var(--s)*.0117);letter-spacing:.16em;text-transform:uppercase;
  color:rgba(0,43,69,.66);border:1px solid var(--line);
  padding:calc(var(--s)*.0033) calc(var(--s)*.0089)}
.person .org.nologo em{display:inline-block}
.person b{display:block;font-family:var(--display);font-weight:700;
  font-size:calc(var(--s)*.0178);color:var(--ink);margin-bottom:calc(var(--s)*.0033)}
.person span{font-size:calc(var(--s)*.015);color:rgba(0,43,69,.8);line-height:1.45;display:block}

@media (max-width:900px){
  /* =====================================================================
     MOBILE: a different design, not a squeezed desktop.

     The desktop layout is a 2D drafting sheet: eight panels pinned at
     multiples of the viewport, a camera that pans across them, scroll-snap
     driving it, and a readout telling you which way the drawing runs. None of
     that survives a phone — there is no sideways gesture worth teaching, the
     panels are taller than the screen so they clipped, and the annotation is
     authored at sizes that cannot shrink to 390px.

     So on a phone the sheet is unrolled into an ordinary document: every panel
     becomes a section, the page scrolls down, and the drafting identity is
     carried by what still works small — the paper, the dashed grid, the frame,
     the mono labels and the corner marks.
     ===================================================================== */

  html{scroll-snap-type:none}

  /* the fixed stage, the camera and the sheet geometry all stand down */
  #stage{position:static;overflow:visible;height:auto}
  #canvas{position:static;transform:none !important;width:auto !important;height:auto !important}
  #scroller{display:none}
  /* the drawing, the route and the chrome that navigates it have no job here */
  #doodle,#route,#hud,#nav,#compass,#vig{display:none !important}
  /* the grid stays: it is the cheapest, most legible part of the identity */
  #grid{position:fixed;inset:0;width:100% !important;height:100% !important;
    transform:none !important}
  #frame{inset:9px}

  body{overflow-x:hidden}

  /* every panel becomes a section in normal flow */
  .panel{position:static !important;width:auto !important;height:auto !important;
    min-height:0;display:block;
    padding:calc(var(--s)*.055) 18px 0 !important}
  .panel:last-of-type{padding-bottom:calc(var(--s)*.06) !important}
  .panel .inner,.panel.center .inner,.panel.wide .inner{
    max-width:none;margin:0;margin-bottom:0;
    padding:22px 20px 24px}
  .panel.center,.panel.wide,.panel.withinsert,.panel.withform,.panel.offline{
    align-items:stretch}

  /* the readout is gone, so the insets that were dodging it come off */
  .panel.wide,.panel.offline{padding-left:18px !important}
  .panel.withinsert{padding-bottom:0 !important}
  .panel.withinsert .inner{margin-left:0}
  .panel.withform{flex-direction:column;gap:14px}
  .panel.withform .inner{max-width:none}
  .formframe{width:100%;max-height:none}

  /* nothing clips any more, so the offline panel reads in its natural order */
  .panel.offline .inner{display:block}
  .panel.offline .stamp,.panel.offline .eyebrow,.panel.offline h3,
  .panel.offline .cta,.panel.offline .fine,.panel.offline p.txt{order:initial}
  .panel.offline p.txt{margin-top:0}
  .panel.offline .cta{margin-top:20px}

  /* type: sized for a phone rather than derived from a 900px-tall sheet */
  h1{font-size:clamp(38px,10.5vw,54px);margin-bottom:12px}
  .sub{font-size:clamp(18px,4.9vw,23px);margin-bottom:20px;max-width:none}
  h2{font-size:clamp(25px,6.7vw,33px)}
  h3{font-size:clamp(23px,6.1vw,30px)}
  .lede,p.txt{font-size:16px;line-height:1.6;max-width:none}
  .daylist{margin-top:16px;gap:11px}
  .daylist li{grid-template-columns:auto 1fr;gap:11px}
  .daylist b{font-size:12px}
  .daylist span{font-size:14.5px;line-height:1.5}
  .eyebrow{font-size:11px;margin-bottom:14px}
  .time{font-size:12px;margin-bottom:12px}
  .meta{gap:14px 26px;padding:12px 0;margin-bottom:20px}
  .meta div{font-size:10.5px}
  .meta b{font-size:16px}
  .fine{font-size:11px;margin-top:14px}
  .stamp{font-size:10.5px;margin-bottom:13px}
  /* full-width tap target, and the travel hint is meaningless on a phone */
  .cta{display:block;width:100%;text-align:center;font-size:19px;padding:16px 20px}
  .hint{display:none}
  /* on a 6,000px document the sticky action matters more, not less */
  #stickyCta{left:16px;right:16px;bottom:16px;width:auto;
    transform:translateY(16px);font-size:17px;padding:15px 18px;
    box-shadow:0 -2px 24px rgba(0,43,69,.16)}
  #stickyCta.on{transform:translateY(0)}

  /* portraits come back — they were hidden wholesale at 1040px, which on a phone
     meant every speaker photo in the agenda simply vanished. Photo beside its
     caption, one person per row. */
  .insert{display:grid !important;grid-template-columns:88px 1fr;align-items:center;
    width:100%;margin-bottom:14px}
  .insert .ph,.insert.two .ph,.insert.three .ph{height:88px !important}
  .insert .cap{border-top:0;padding:8px 12px;font-size:10px;gap:3px}
  .insert .cap b{font-size:12.5px}
  .insert .ph + .cap + .ph{border-top:1px solid rgba(0,43,69,.18)}
  .insert .ph + .cap + .ph + .cap{border-top:1px solid rgba(0,43,69,.18)}
  .insert .ph .vlab{display:none}

  .people{grid-template-columns:repeat(2,1fr);gap:18px 14px;margin-top:14px}
  .person .ph{height:132px;margin-bottom:8px}
  .person b{font-size:14.5px}
  .person span{font-size:12.5px}
  .person .org img{height:15px;max-width:88px}

  /* the four figures live only in the drawing on desktop; on a phone the drawing
     is gone, so they are stated as text instead of being lost */
  .mkeys{display:grid !important;grid-template-columns:1fr 1fr;
    gap:1px;background:rgba(0,43,69,.22);border:1px solid rgba(0,43,69,.22);
    margin:22px 0 18px}
  .mkeys div{background:#FFFFFF;padding:11px 12px 12px}
  .mkeys b{display:block;font-family:var(--display);font-weight:900;font-size:19px;
    letter-spacing:-.02em;color:var(--fuchsia);margin-bottom:3px;line-height:1.05}
  .mkeys span{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.08em;
    text-transform:uppercase;color:rgba(0,43,69,.72);line-height:1.35}
  .mloop{display:block !important;font-family:var(--mono);font-size:10.5px;
    letter-spacing:.1em;text-transform:uppercase;margin:0 0 4px;line-height:1.6}
  .mloop s{color:rgba(0,43,69,.5);display:block;margin-bottom:5px}
  .mloop em{font-style:normal;color:var(--fuchsia);display:block}
}

/* Only the narrowest phones go single-column. At 390px two columns still give a
   176px photo, and one column made the speaker section 1400px tall on its own. */
@media (max-width:359px){
  .people{grid-template-columns:1fr}
  .mkeys{grid-template-columns:1fr}
  .person .ph{height:168px}
}

/* =========================================================================
   HubSpot adaptation (InboundLabs) — additions only, never edits above.
   ========================================================================= */

/* Each station module renders inside a hs_cos_wrapper; it must behave as a
   neutral block so the absolute (desktop) and static (mobile) panel layouts
   are unaffected by the extra ancestor. */
#canvas > .hs_cos_wrapper{display:block}

/* The blueprint gave the LAST panel its mobile bottom padding via
   .panel:last-of-type — but with one panel per module wrapper every panel is
   now :last-of-type inside its own wrapper. Restore the original intent:
   only the final station keeps the closing padding. */
@media (max-width:900px){
  #canvas .panel:last-of-type{padding-bottom:0 !important}
  #canvas > *:last-child .panel,
  #canvas > .panel:last-child{padding-bottom:calc(var(--s)*.06) !important}
}

/* Reduced-motion honours — kept at the very end of the file on purpose:
   HubSpot's template-asset CSS processor aborts at this at-rule and drops
   everything AFTER it, so last position limits the blast radius to this
   block alone. Do not move these up. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  #stickyCta{transition:none}
}