/* ============================================================
   GTS Brand Library - Site  ·  template.css
   Ported from the approved front-end mockup. Brand accent
   colours arrive at runtime from the resolver (--accent on
   :root, injected server-side); the [data-brand] blocks below
   are fallbacks/placeholders only.
   ============================================================ */

:root{
  --r:7px; --rs:4.5px; --rb:14px; --t:.25s ease;
  --f-disp:'Figtree',sans-serif; --f-body:'DM Sans',sans-serif; --f-mono:'DM Mono',monospace;
  --accent:#1f8fd6; --accent2:#3f3f9e; --brand-2:#3f3f9e;
}
[data-theme="dark"]{
  --bg:#0a0c10;
  --surf:color-mix(in srgb,var(--accent) 13%,#14171f);
  --surf2:color-mix(in srgb,var(--accent) 16%,#1c202b);
  --surf3:color-mix(in srgb,var(--accent) 20%,#262b38);
  --txt:#eef1f7; --txt2:#9aa3b5; --txt3:#5b647a;
  --bdr:color-mix(in srgb,var(--accent) 20%,rgba(255,255,255,.08));
  --bdr2:color-mix(in srgb,var(--accent) 28%,rgba(255,255,255,.14));
  --sh:0 10px 40px rgba(0,0,0,.5);
}
[data-theme="light"]{
  --bg:#f5f6f8;
  --surf:color-mix(in srgb,var(--accent) 3%,#ffffff);
  --surf2:color-mix(in srgb,var(--accent) 12%,#ffffff);
  --surf3:color-mix(in srgb,var(--accent) 19%,#ffffff);
  --txt:#14181f; --txt2:#46505f; --txt3:#8a93a6;
  --bdr:color-mix(in srgb,var(--accent) 22%,transparent);
  --bdr2:color-mix(in srgb,var(--accent) 34%,transparent);
  --sh:0 12px 40px color-mix(in srgb,var(--accent) 16%,rgba(0,0,0,.05));
}
/* Fallback brand skins (the resolver overrides --accent/--accent2 at runtime). */
[data-brand="goldwell"]{--accent:#c89a3c;--brand-2:#1a1a1a}
[data-brand="kms"]     {--accent:#e8472d;--brand-2:#141414}
[data-brand="kerasilk"]{--accent:#a8678c;--brand-2:#2a2230}
[data-brand="zone"]    {--accent:#1f8fd6;--brand-2:#3f3f9e}

*{box-sizing:border-box;margin:0;padding:0}
/* --body-bg is the Page Builder's optional page colour; unset, the theme's own
   --bg stands. Same fallback shape for the menu strip and footer below. */
body.gtsbl{font-family:var(--f-body);background:var(--body-bg,var(--bg));color:var(--txt);font-size:16px;-webkit-font-smoothing:antialiased;transition:background var(--t),color var(--t)}
body.gtsbl a{color:inherit;text-decoration:none}
body.gtsbl svg{display:block}
body.gtsbl img{max-width:100%}
.gtsbl-shell{max-width:1280px;margin:0 auto;padding:0 26px}

/* ---- brand nav ---- */
.gtsbl-nav{position:sticky;top:0;z-index:50;backdrop-filter:blur(14px);background:var(--nav-bg,color-mix(in srgb,var(--bg) 78%,transparent));border-bottom:1px solid var(--bdr)}
.gtsbl-nav .nav-in{display:flex;align-items:center;gap:26px;height:66px}
.gtsbl-nav .brand{display:flex;align-items:center;gap:13px}
.gtsbl-nav .nm-wide{font-family:var(--f-disp);font-weight:600;font-size:24px;letter-spacing:0;color:var(--txt);line-height:1}
.gtsbl-nav .nm-logo{height:34px;width:auto;max-width:230px;object-fit:contain;display:block}
.gtsbl-nav .nm-zone{font-size:12px;color:var(--txt3);letter-spacing:.04em;border-left:1px solid var(--bdr);padding-left:12px}
.gtsbl-nav .nav-right{margin-left:auto;display:flex;align-items:center;gap:12px}
.gtsbl-nav .gtsbl-mainnav{display:flex;align-items:center;gap:4px}
.gtsbl-nav .gtsbl-mn-i{padding:9px 16px;border-radius:9px;color:var(--txt2);font-weight:600;font-size:14.5px;white-space:nowrap;transition:color var(--t),background var(--t)}
.gtsbl-nav .gtsbl-mn-i:hover{color:var(--txt);background:var(--surf2)}

/* ---- main ---- */
.gtsbl-main{min-height:60vh;padding-bottom:30px}

/* ---- hero ---- */
.gtsbl .hero{position:relative;margin-top:22px;border-radius:var(--r);overflow:hidden;min-height:420px;display:flex;align-items:flex-end;box-shadow:var(--sh)}
.gtsbl .hero-bg{position:absolute;inset:0;background:linear-gradient(120deg,var(--brand-2),var(--accent));opacity:.92}
.gtsbl .hero-bg::after{content:"";position:absolute;inset:0;background:radial-gradient(120% 90% at 80% 10%,transparent,rgba(0,0,0,.55))}
.gtsbl .hero-in{position:relative;padding:42px 44px;max-width:640px;color:#fff}
.gtsbl .eyebrow{font-family:var(--f-mono);font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;opacity:.85;margin-bottom:14px;display:flex;align-items:center;gap:9px}
.gtsbl .eyebrow .chip{background:rgba(255,255,255,.18);padding:3px 9px;border-radius:20px}
.gtsbl .hero h1{font-family:var(--f-disp);font-weight:600;font-size:46px;line-height:1.06;letter-spacing:-.01em;margin-bottom:14px}
.gtsbl .hero p{font-size:16px;line-height:1.55;opacity:.9;max-width:480px;margin-bottom:22px}
.gtsbl .play{display:inline-flex;align-items:center;gap:10px;background:#fff;color:#111;font-weight:600;font-size:15.5px;padding:13px 23px;border-radius:30px;cursor:pointer}
.gtsbl .play svg{width:16px;height:16px;fill:#111}

/* ---- section heads ---- */
.gtsbl .sec{margin-top:42px}
.gtsbl .sec-head{display:flex;align-items:baseline;gap:14px;margin-bottom:16px}
.gtsbl .sec-head h2{font-family:var(--f-disp);font-weight:600;font-size:25px;letter-spacing:-.01em}
.gtsbl .sec-head a{margin-left:auto;font-size:14px;color:var(--accent);font-weight:600}

/* ---- category gallery ---- */
.gtsbl .cats{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:16px}
.gtsbl .cat{position:relative;border-radius:var(--r);overflow:hidden;aspect-ratio:1/1;cursor:pointer;display:flex;align-items:flex-end;box-shadow:var(--sh)}
.gtsbl .cat .bg{position:absolute;inset:0;background:linear-gradient(160deg,#8d877e,#2b2825);transition:transform var(--t)}
.gtsbl .cat:hover .bg{transform:scale(1.06)}
.gtsbl .cat .ov{position:absolute;inset:0;background:linear-gradient(transparent,rgba(0,0,0,.6))}
.gtsbl .cat .lbl{position:relative;padding:16px;color:#fff}
.gtsbl .cat .lbl h3{font-family:var(--f-disp);font-weight:600;font-size:20px}
.gtsbl .cat .lbl span{font-family:var(--f-mono);font-size:13px;opacity:.85}

/* ---- video rail ---- */
.gtsbl .rail{display:flex;gap:15px;overflow-x:auto;padding-bottom:8px;scroll-snap-type:x mandatory}
.gtsbl .rail::-webkit-scrollbar{height:6px}.gtsbl .rail::-webkit-scrollbar-thumb{background:var(--surf3);border-radius:3px}
.gtsbl .vc{flex:0 0 250px;scroll-snap-align:start;cursor:pointer}
.gtsbl .vc-thumb{position:relative;border-radius:var(--rs);overflow:hidden;aspect-ratio:16/9;background:linear-gradient(135deg,#9a948c,#332f2b)}
.gtsbl .vc-thumb .dur{position:absolute;bottom:8px;right:8px;background:rgba(0,0,0,.72);color:#fff;font-family:var(--f-mono);font-size:12px;padding:2px 7px;border-radius:var(--rs)}
/* ---- watched state (GTS Core Video Manager progress) ----
   A tick, not a banner. This is a quiet "you've seen this" for someone
   scanning a rail, so it must not compete with the lock badge or the title.
   Watched tiles are also dimmed slightly - the strongest signal at a glance is
   contrast, not iconography. */
.gtsbl .vc-thumb.is-watched{filter:brightness(.72)}
.gtsbl .vc-seen{position:absolute;top:8px;right:8px;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:var(--accent);box-shadow:0 2px 8px rgba(0,0,0,.45)}
.gtsbl .vc-seen svg{width:14px;height:14px;fill:none;stroke:#fff;stroke-width:3;stroke-linecap:round;stroke-linejoin:round}
/* Resume bar for a part-watched video: the one piece of information a
   half-finished tile can give that the title cannot. */
.gtsbl .vc-bar{position:absolute;left:0;right:0;bottom:0;height:4px;background:rgba(0,0,0,.55)}
.gtsbl .vc-bar i{display:block;height:100%;background:var(--accent);border-radius:0 2px 2px 0}
.gtsbl .vc-t{font-weight:600;font-size:15.5px;margin-top:10px;line-height:1.35}
.gtsbl .vc-m{font-size:13px;color:var(--txt3);margin-top:3px;font-family:var(--f-mono)}
.gtsbl .vgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:16px}
.gtsbl-main .avs-related{display:none}
.gtsbl .vgrid .vc{flex:none}

/* ---- premium / paywall gate ---- */
.gtsbl .premium{margin-top:42px;background:var(--surf);border:1px solid var(--bdr);border-radius:var(--r);padding:24px;position:relative;overflow:hidden}
.gtsbl .premium::before{content:"";position:absolute;right:-60px;top:-60px;width:220px;height:220px;border-radius:50%;background:radial-gradient(var(--accent),transparent 70%);opacity:.25}
.gtsbl .premium .ph{display:flex;align-items:center;gap:11px;margin-bottom:6px}
.gtsbl .premium .ph svg{width:20px;height:20px;stroke:var(--accent)}
.gtsbl .premium .ph h2{font-family:var(--f-disp);font-weight:700;font-size:20px}
.gtsbl .premium .pd{color:var(--txt2);font-size:13.5px;margin-bottom:18px;max-width:560px}
.gtsbl .locked-rail{display:flex;gap:15px;overflow:hidden}
.gtsbl .lc{flex:0 0 230px;position:relative;border-radius:var(--rs);overflow:hidden;aspect-ratio:16/9}
.gtsbl .lc .bg{position:absolute;inset:0;background:linear-gradient(135deg,var(--surf3),var(--surf2));filter:blur(1px)}
.gtsbl .lc .lk{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;color:var(--txt2);background:rgba(0,0,0,.35)}
.gtsbl .lc .lk svg{width:22px;height:22px;stroke:var(--accent)}
.gtsbl .lc .lk span{font-size:11.5px;font-weight:600}
.gtsbl .upgrade{margin-top:18px;display:inline-flex;align-items:center;gap:9px;background:var(--accent);color:#fff;font-weight:700;font-size:13.5px;padding:12px 22px;border-radius:30px;cursor:pointer}

/* ---- live badge ---- */
.gtsbl .live{display:inline-flex;align-items:center;gap:7px;font-size:11.5px;font-weight:700;color:#fff;background:#dc2626;padding:5px 11px;border-radius:20px}
.gtsbl .live .d{width:7px;height:7px;border-radius:50%;background:#fff;animation:gtsbl-pulse 1.4s infinite}
@keyframes gtsbl-pulse{0%,100%{opacity:1}50%{opacity:.3}}

/* ---- footer ---- */
/* Footer background and text are separate controls on purpose: a dark footer
   under a light page needs its own text colour, and one picker cannot do that. */
.gtsbl-foot{margin-top:60px;border-top:1px solid var(--bdr);background:var(--foot-bg,transparent)}
.gtsbl-foot .foot-in{padding-top:26px;padding-bottom:50px;color:var(--foot-txt,var(--txt3));font-size:13.5px;display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.gtsbl-foot .foot-in a{color:inherit}
.gtsbl-foot .fr{margin-left:auto;font-family:var(--f-mono)}

@media(max-width:760px){
  .gtsbl .hero h1{font-size:32px}
  .gtsbl-shell{padding:0 16px}
  .gtsbl .hero{min-height:330px}
  .gtsbl .hero-in{padding:26px 20px}
  .gtsbl-hero.is-noimg{min-height:300px}
  .gtsbl-hero .hero-in{padding:26px 20px}
  .gtsbl-hero h1{font-size:30px}
  .gtsbl .sec{margin-top:32px}
  .gtsbl .sec-head h2{font-size:21px}
  .gtsbl .cats{gap:13px}
  .gtsbl .rail{display:grid;grid-template-columns:repeat(2,1fr);gap:12px;overflow:visible;scroll-snap-type:none}
  .gtsbl .vc{flex:none;width:auto}
  .gtsbl-bcards{gap:15px}
  .gtsbl-bcard .bc-name{font-size:22px}
  .gtsbl-main .login,.gtsbl-main .registration,.gtsbl-main .profile,.gtsbl-main .reset,.gtsbl-main .remind,.gtsbl-main .edit{margin:24px auto 44px}
  .gtsbl-main .login form,.gtsbl-main .registration form,.gtsbl-main .profile,.gtsbl-main .reset form,.gtsbl-main .remind form{padding:22px}
}

/* ---- adaptive collapsing hero (portal) ---- */
.gtsbl-hero{position:relative;margin-top:18px;border-radius:var(--r);overflow:hidden;box-shadow:var(--sh);background:var(--brand-2);min-height:240px}
.gtsbl-hero .hero-img{display:block;width:100%;height:auto}
.gtsbl-hero::after{content:"";position:absolute;inset:0;background:linear-gradient(transparent 42%,rgba(0,0,0,.6));pointer-events:none;z-index:1}
.gtsbl-hero.is-noimg{min-height:420px}
.gtsbl-hero .hero-bg{position:absolute;inset:0;background:linear-gradient(120deg,var(--brand-2),var(--accent));opacity:.92}
.gtsbl-hero .hero-bg::after{content:"";position:absolute;inset:0;background:radial-gradient(120% 90% at 80% 10%,transparent,rgba(0,0,0,.6))}
.gtsbl-hero .hero-in{position:absolute;left:0;bottom:0;padding:40px 42px;max-width:620px;color:#fff;z-index:2}
.gtsbl-hero .eyebrow{font-family:var(--f-mono);font-size:12.5px;letter-spacing:.14em;text-transform:uppercase;opacity:.85;margin-bottom:13px;display:flex;align-items:center;gap:9px}
.gtsbl-hero .eyebrow .chip{background:rgba(255,255,255,.18);padding:3px 9px;border-radius:20px}
.gtsbl-main .gtsbl-hero h1{font-family:var(--f-disp);font-weight:600;font-size:46px;line-height:1.06;letter-spacing:-.01em;margin-bottom:16px;color:#fff}
.gtsbl-hero .hero-sub{font-family:var(--f-body);font-size:16px;line-height:1.5;color:#fff;opacity:.9;max-width:520px;margin:-8px 0 18px}
.gtsbl-hero .play{display:inline-flex;align-items:center;gap:10px;background:#fff;color:#111;font-weight:600;font-size:15.5px;padding:13px 23px;border-radius:30px;cursor:pointer}
.gtsbl-hero .play svg{width:16px;height:16px;fill:#111}
.gtsbl-hero .hero-slim{position:absolute;left:42px;top:0;bottom:0;display:flex;align-items:center;gap:13px;color:#fff;opacity:var(--slim-op,0);pointer-events:none;transition:opacity .12s linear}
.gtsbl-hero .hero-slim .hs-t{font-family:var(--f-disp);font-weight:600;font-size:19px}
.gtsbl-hero .hero-slim .hs-m{font-family:var(--f-mono);font-size:12px;opacity:.8}
.gtsbl-hero.is-inner{height:92px}
.gtsbl-hero.is-inner .hero-in{opacity:0}
.gtsbl-hero.is-inner .hero-slim{opacity:1}
.gtsbl-sec{margin-top:38px}

/* ---- paywall / locked states ---- */
.gtsbl-hero .play.is-locked{background:color-mix(in srgb,var(--accent) 88%,#000);color:#fff}
.gtsbl-hero .play.is-locked svg{width:15px;height:15px;stroke:#fff;fill:none}
.cat.is-locked{cursor:pointer}
.cat .lock-badge{position:absolute;top:10px;right:10px;z-index:2;display:inline-flex;align-items:center;gap:5px;font-family:var(--f-mono);font-size:11px;font-weight:700;letter-spacing:.04em;color:#fff;background:rgba(18,20,24,.82);padding:4px 9px;border-radius:20px}
.cat .lock-badge svg{width:11px;height:11px;stroke:#fff}
.cat.is-locked .bg{filter:saturate(.55) brightness(.7)}
.vc.is-locked .vc-thumb{filter:saturate(.5) brightness(.65)}
.vc .vc-lock{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;color:#fff;background:rgba(0,0,0,.32)}
.vc .vc-lock svg{width:22px;height:22px;stroke:var(--accent)}
.vc .vc-lock em{font-family:var(--f-mono);font-size:11.5px;font-style:normal;font-weight:700;letter-spacing:.04em;color:#fff}
.vc.is-locked .vc-m{color:var(--accent);font-weight:600}


/* ---- placeholder Premium upgrade modal ---- */
.gtsbl-upgrade{position:fixed;inset:0;z-index:200;display:none;align-items:center;justify-content:center;padding:20px}
.gtsbl-upgrade.is-open{display:flex}
.gtsbl-upgrade .up-backdrop{position:absolute;inset:0;background:rgba(4,6,11,.72);backdrop-filter:blur(6px)}
.gtsbl-upgrade .up-card{position:relative;width:100%;max-width:420px;background:var(--surf);border:1px solid var(--bdr);border-radius:calc(var(--r) + 4px);box-shadow:0 30px 80px rgba(0,0,0,.6);overflow:hidden;animation:upIn .22s ease}
@keyframes upIn{from{opacity:0;transform:translateY(14px) scale(.98)}to{opacity:1;transform:none}}
.gtsbl-upgrade .up-card::before{content:"";position:absolute;left:0;right:0;top:0;height:3px;background:linear-gradient(90deg,var(--accent),var(--accent2))}
.gtsbl-upgrade .up-x{position:absolute;top:12px;right:12px;width:32px;height:32px;border:0;border-radius:50%;background:var(--surf2,rgba(255,255,255,.06));color:var(--txt2);font-size:20px;line-height:1;cursor:pointer}
.gtsbl-upgrade .up-x:hover{color:var(--txt)}
.gtsbl-upgrade .up-body{padding:30px 26px 24px}
.gtsbl-upgrade .up-eyebrow{font-family:var(--f-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--accent);display:flex;align-items:center;gap:8px;margin-bottom:12px}
.gtsbl-upgrade .up-preview{font-family:var(--f-body);letter-spacing:.04em;color:var(--txt3);border:1px solid var(--bdr);border-radius:var(--rb);padding:2px 8px;text-transform:none;font-size:10px}
.gtsbl-upgrade .up-h{font-family:var(--f-disp);font-weight:600;font-size:27px;letter-spacing:-.01em;line-height:1.08;margin-bottom:8px;color:var(--txt)}
.gtsbl-upgrade .up-sub{font-size:14.5px;line-height:1.55;color:var(--txt2);margin-bottom:18px}
.gtsbl-upgrade .up-toggle{display:flex;gap:6px;background:var(--surf2,rgba(255,255,255,.05));border:1px solid var(--bdr);border-radius:30px;padding:4px;margin-bottom:16px}
.gtsbl-upgrade .up-seg{flex:1;border:0;background:none;color:var(--txt2);font-family:var(--f-body);font-weight:600;font-size:12.5px;padding:8px 10px;border-radius:24px;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:6px}
.gtsbl-upgrade .up-seg em{font-style:normal;font-size:10px;color:var(--accent);font-family:var(--f-mono)}
.gtsbl-upgrade .up-seg.is-on{background:var(--surf);color:var(--txt);box-shadow:0 1px 4px rgba(0,0,0,.3)}
.gtsbl-upgrade .up-price{display:flex;align-items:baseline;gap:7px;margin-bottom:16px}
.gtsbl-upgrade .up-amt{font-family:var(--f-disp);font-weight:700;font-size:34px;color:var(--txt);line-height:1}
.gtsbl-upgrade .up-per{font-size:13px;color:var(--txt2)}
.gtsbl-upgrade .up-sample{margin-left:auto;font-family:var(--f-mono);font-size:10px;color:var(--txt3);border:1px dashed var(--bdr);border-radius:var(--rs);padding:3px 7px}
.gtsbl-upgrade .up-feats{list-style:none;margin:0 0 20px;padding:0;display:grid;gap:9px}
.gtsbl-upgrade .up-feats li{position:relative;padding-left:24px;font-size:14.5px;color:var(--txt)}
.gtsbl-upgrade .up-feats li::before{content:"";position:absolute;left:0;top:3px;width:15px;height:15px;border-radius:50%;background:color-mix(in srgb,var(--accent) 22%,transparent)}
.gtsbl-upgrade .up-feats li::after{content:"";position:absolute;left:5px;top:7px;width:5px;height:8px;border:solid var(--accent);border-width:0 2px 2px 0;transform:rotate(45deg)}
.gtsbl-upgrade .up-cta{width:100%;border:0;background:var(--accent);color:#fff;font-family:var(--f-body);font-weight:600;font-size:15.5px;padding:14px;border-radius:30px;cursor:pointer;transition:filter var(--t)}
.gtsbl-upgrade .up-cta:hover{filter:brightness(1.07)}
.gtsbl-upgrade .up-cta.is-soon{background:var(--surf2,rgba(255,255,255,.07));color:var(--txt2);cursor:default}
.gtsbl-upgrade .up-note{margin-top:12px;text-align:center;font-size:12px;color:var(--txt3);line-height:1.5}


/* ---- nav auth (login / logout) ---- */
.gtsbl-nav .gtsbl-auth{display:inline-flex;align-items:center;font-size:14.5px;font-weight:600;padding:9px 16px;border-radius:9px;transition:background var(--t),color var(--t),filter var(--t)}
.gtsbl-nav .gtsbl-signin{background:#16181c;color:#fff}
.gtsbl-nav .gtsbl-signin:hover{filter:brightness(1.07)}
/* Create account (0.79.37) sits LEFT of Sign in and reads as the secondary of
   the pair: Sign in keeps the filled treatment it has always had, so a returning
   visitor's eye lands in the same place. Only rendered where the install accepts
   registrations - see index.php. */
.gtsbl-nav .gtsbl-signup{background:transparent;color:var(--txt);border:1px solid var(--bdr2);white-space:nowrap}
.gtsbl-nav .gtsbl-signup:hover{background:var(--surf2)}
/* Phones: the header already stacks to three centred rows below 600px and the
   controls row is the tightest of them. Trim both buttons rather than let the
   pair wrap or push the row wider than the screen.

   min-height:44px is NOT decoration. Trimming the padding first put them at 35px
   and 33px - measured, in a 390px probe - which is under the tap target, the
   exact mistake 0.79.24 made with the hero play button. On a phone these two are
   the only controls in the header, so they get the full 44. Measured after:
   both 44, side by side, pair ends at x=297 of 390, no overflow. */
@media(max-width:600px){
  .gtsbl-nav .gtsbl-auth{font-size:13.5px;padding:8px 12px;min-height:44px}
}
.gtsbl-nav .gtsbl-logout{color:var(--txt2);border:1px solid var(--bdr2)}
.gtsbl-nav .gtsbl-logout:hover{color:var(--txt);background:var(--surf2)}
.gtsbl-nav .gtsbl-acct{font-size:14px;font-weight:600;color:var(--txt);max-width:170px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gtsbl-nav a.gtsbl-acct{cursor:pointer}
.gtsbl-nav a.gtsbl-acct:hover{color:var(--accent);text-decoration:underline}
@media(max-width:760px){.gtsbl-nav .gtsbl-acct{display:none}}

/* ---- zone home (KAO brand picker) ---- */
.gtsbl-zhero{padding:48px 0 30px;text-align:center;max-width:720px;margin:0 auto}
.gtsbl-zhero .zh-eyebrow{font-family:var(--f-mono);font-size:12.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--accent)}
.gtsbl-main .gtsbl-zhero h1{font-family:var(--f-disp);font-weight:600;font-size:46px;line-height:1.08;letter-spacing:-.01em;margin:14px 0 12px;color:var(--txt)}
.gtsbl-zhero p{font-size:17px;line-height:1.55;color:var(--txt2)}
.gtsbl-bcards{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,340px));justify-content:center;gap:20px;margin-top:14px;padding-bottom:34px}
.gtsbl-zchoose{margin-top:34px}
/* The family row used to switch the grid out for a flex row of 300px 16/10
   cards, so the same artwork was framed two different ways on two pages.
   Troy: "the KAO and the 3 brands would be the same width and same image."
   It now keeps the grid and the 1/1 card, and only trims the section padding -
   one shape, one width, one crop, everywhere. */
.gtsbl-bcards-x{padding-bottom:8px}
.gtsbl-bcard{position:relative;display:block;border-radius:var(--r);overflow:hidden;aspect-ratio:1/1;box-shadow:var(--sh);isolation:isolate}
.gtsbl-bcard .bc-bg{position:absolute;inset:0;background-size:cover;background-position:top center;background-color:var(--bc);background-image:linear-gradient(150deg,color-mix(in srgb,var(--bc) 78%,#000),var(--bc2));transition:transform .4s ease}
.gtsbl-bcard:hover .bc-bg{transform:scale(1.04)}
.gtsbl-bcard .bc-ov{position:absolute;inset:0;background:linear-gradient(180deg,transparent 40%,rgba(0,0,0,.18) 60%,rgba(0,0,0,.82))}
.gtsbl-bcard .bc-in{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;gap:6px;padding:16px 18px;color:#fff}
.gtsbl-bcard .bc-name{font-family:var(--f-disp);font-weight:600;font-size:25px;line-height:1.05;letter-spacing:-.01em;text-shadow:0 1px 12px rgba(0,0,0,.45)}
.gtsbl-bcard .bc-go{display:inline-flex;align-items:center;gap:8px;font-family:var(--f-mono);font-size:13px;letter-spacing:.06em;text-transform:uppercase;opacity:.92}
.gtsbl-bcard .bc-go svg{width:18px;height:18px;transition:transform var(--t)}
.gtsbl-bcard:hover .bc-go svg{transform:translateX(4px)}
@media(max-width:760px){.gtsbl-zhero h1{font-size:34px}.gtsbl-zhero{padding:30px 0 22px}}


/* ---- account pages (com_users forms inside the KAO shell) ---- */
.gtsbl-main .login,.gtsbl-main .registration,.gtsbl-main .profile,
.gtsbl-main .reset,.gtsbl-main .remind,.gtsbl-main .edit{max-width:460px;margin:40px auto 60px}
.gtsbl-main .login form,.gtsbl-main .registration form,.gtsbl-main .profile,
.gtsbl-main .reset form,.gtsbl-main .remind form{background:var(--surf);border:1px solid var(--bdr);border-radius:var(--r);padding:30px;box-shadow:var(--sh)}
.gtsbl-main h1,.gtsbl-main h2.page-header,.gtsbl-main .page-header h1{font-family:var(--f-disp);font-weight:600;font-size:30px;letter-spacing:-.01em;margin-bottom:18px;color:var(--txt)}
.gtsbl-main label{display:block;font-size:14px;font-weight:600;color:var(--txt2);margin-bottom:6px}
.gtsbl-main input[type=text],.gtsbl-main input[type=email],.gtsbl-main input[type=password],
.gtsbl-main input[type=tel],.gtsbl-main input:not([type]){width:100%;font-family:var(--f-body);font-size:15px;padding:12px 14px;border:1px solid var(--bdr2);border-radius:var(--rs);background:var(--surf2);color:var(--txt);margin-bottom:16px}
.gtsbl-main input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 18%,transparent)}
.gtsbl-main fieldset{border:0;padding:0;margin:0;min-width:0}
.gtsbl-main .btn,.gtsbl-main .btn-primary,.gtsbl-main button[type=submit],.gtsbl-main input[type=submit]{display:inline-flex;align-items:center;justify-content:center;gap:8px;background:var(--accent);color:#fff;border:0;font-family:var(--f-body);font-weight:600;font-size:15px;padding:12px 22px;border-radius:30px;cursor:pointer;transition:filter var(--t)}
.gtsbl-main .btn:hover,.gtsbl-main button[type=submit]:hover{filter:brightness(1.07)}
.gtsbl-main .btn-secondary,.gtsbl-main a.btn{background:var(--surf2);color:var(--txt);border:1px solid var(--bdr2)}
.gtsbl-main nav ul,.gtsbl-main ul.nav{list-style:none;padding:0;margin:18px 0 0;display:flex;gap:16px;flex-wrap:wrap;font-size:14px}
.gtsbl-main nav a{color:var(--accent);font-weight:600}
.gtsbl-main .control-group{margin-bottom:6px}
.gtsbl-main .alert{border-radius:var(--rs);padding:12px 14px;margin-bottom:16px;background:var(--surf2);border:1px solid var(--bdr2);font-size:14px}


/* ---- brand-jump bar (top utility bar) ---- */
.gtsbl-brandbar{background:var(--brandbar-bg,var(--surf2));border-bottom:1px solid var(--bdr)}
.gtsbl-brandbar .bb-in{display:flex;align-items:center;gap:12px;min-height:58px;padding:8px 0}
.gtsbl-brandbar .bb-home{display:inline-flex;align-items:center;gap:8px;color:var(--txt2);font-weight:700;font-size:14.5px;padding:9px 15px;border-radius:30px;border:1px solid var(--bdr);background:var(--surf);flex-shrink:0}
.gtsbl-brandbar .bb-home svg{width:15px;height:15px;stroke:currentColor}
.gtsbl-brandbar .bb-home:hover,.gtsbl-brandbar .bb-home.on{color:var(--txt)}
.gtsbl-brandbar .bb-brands{display:flex;align-items:center;gap:6px;margin-left:auto;overflow-x:auto;scrollbar-width:none}
.gtsbl-brandbar .bb-brands::-webkit-scrollbar{display:none}
.gtsbl-brandbar .bb-b{display:inline-flex;align-items:center;gap:8px;padding:9px 17px;border-radius:30px;color:var(--txt2);font-weight:700;font-size:14.5px;border:1px solid var(--bdr);background:var(--surf);white-space:nowrap;transition:color var(--t),background var(--t),border-color var(--t)}
.gtsbl-brandbar .bb-b .bb-sw{width:11px;height:11px;border-radius:4px;background:var(--bc);flex-shrink:0}
.gtsbl-brandbar .bb-b:hover{color:var(--txt);background:var(--surf3)}
.gtsbl-brandbar .bb-b.on{color:var(--txt);border-color:color-mix(in srgb,var(--bc) 55%,transparent);background:color-mix(in srgb,var(--bc) 12%,transparent)}
.gtsbl-brandbar .bb-classes{display:inline-flex;align-items:center;gap:8px;padding:9px 17px;border-radius:30px;color:var(--txt2);font-weight:700;font-size:14.5px;border:1px solid var(--bdr);background:var(--surf);white-space:nowrap;flex-shrink:0;transition:color var(--t),background var(--t),border-color var(--t)}
.gtsbl-brandbar .bb-classes svg{width:15px;height:15px;stroke:currentColor}
.gtsbl-brandbar .bb-classes:hover{color:var(--txt);background:var(--surf3)}
.gtsbl-brandbar .bb-classes.on{color:var(--txt);border-color:color-mix(in srgb,var(--txt2) 42%,transparent);background:var(--surf3)}
.gtsbl-brandbar .bb-div{width:1px;height:24px;background:var(--bdr);flex-shrink:0;margin:0 3px}

/* one consistent brand category nav — header row on every brand page */
/* The strip is a CHILD of .gtsbl-nav, so transparent means it simply shows the
   nav's own background - which is exactly the behaviour every existing brand
   already has. Setting --catmenu-bg paints over it; no markup change, and no
   brand grows a seam by upgrading. */
.gtsbl-nav .nav-cats{border-top:1px solid var(--bdr);background:var(--catmenu-bg,transparent)}
.gtsbl-nav .nav-cats-in{display:flex;gap:4px;height:50px;align-items:center;overflow-x:auto;scrollbar-width:none}
.gtsbl-nav .nav-cats-in::-webkit-scrollbar{display:none}
.gtsbl-nav .nav-cats a{position:relative;padding:9px 15px;border-radius:9px;color:var(--txt2);font-weight:600;font-size:14.5px;white-space:nowrap;transition:color var(--t),background var(--t)}
.gtsbl-nav .nav-cats a:hover{color:var(--txt);background:var(--surf2)}
.gtsbl-nav .nav-cats a.on{color:var(--accent)}
.gtsbl-nav .nav-cats a.on::after{content:"";position:absolute;left:15px;right:15px;bottom:-1px;height:2px;border-radius:2px;background:var(--accent)}
/* a category the visitor cannot open yet - the strip used to link straight
   through to it with no marker at all (0.79.42) */
.gtsbl-nav .nav-cats a.is-locked{color:var(--txt3);display:inline-flex;align-items:center;gap:6px}
.gtsbl-nav .nav-cats a.is-locked:hover{color:var(--txt2)}
.gtsbl-nav .nav-cats a.is-locked .cn-lock{width:13px;height:13px;flex:0 0 13px;opacity:.85}
.gtsbl-nav .nav-cats-classes{margin-left:auto;color:var(--accent);background:color-mix(in srgb,var(--accent) 10%,transparent)}
.gtsbl-nav .nav-cats-classes:hover{color:var(--accent);background:color-mix(in srgb,var(--accent) 17%,transparent)}
@media(max-width:760px){
  .gtsbl-nav .nav-cats-in{height:46px}
  .gtsbl-nav .nav-cats a{padding:9px 13px}
}
@media(max-width:760px){
  .gtsbl-brandbar .bb-home{padding:9px 13px;font-size:14px}
  .gtsbl-brandbar .bb-b{padding:10px 15px;font-size:14px;gap:7px}
  .gtsbl-brandbar .bb-in{gap:8px}
}


/* ---- KAO home banner ---- */
.gtsbl-banner{margin-top:18px;border-radius:var(--r);overflow:hidden;height:260px;background-image:var(--img-d);background-size:cover;background-position:center;box-shadow:var(--sh)}
.gtsbl-zbanner{display:block;width:100%;height:auto;margin-top:18px;border-radius:var(--r);box-shadow:var(--sh)}
.gtsbl-zheroimg{margin:0 0 4px}
.gtsbl-phero{position:relative;border-radius:var(--r);overflow:hidden;min-height:460px;display:flex;align-items:flex-end;box-shadow:var(--sh);margin:0 0 8px}
.gtsbl-phero-img{position:absolute;inset:0}
.gtsbl-phero-img img{width:100%;height:100%;object-fit:cover;display:block}
.gtsbl-phero::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,rgba(18,20,24,.62),rgba(18,20,24,.12) 42%,transparent 64%),linear-gradient(0deg,rgba(18,20,24,.5),transparent 46%)}
.gtsbl-phero-in{position:relative;z-index:1;width:100%;padding:0 36px 36px}
.gtsbl-phero .ph-eyebrow{display:block;font-size:12px;font-weight:600;letter-spacing:.22em;text-transform:uppercase;color:rgba(255,255,255,.85);margin-bottom:12px}
.gtsbl-phero .ph-word{font-family:'DM Sans',sans-serif;font-weight:300;font-size:clamp(42px,7vw,88px);line-height:.95;letter-spacing:-.015em;color:#fff;margin:0;text-shadow:0 2px 26px rgba(0,0,0,.3)}
.gtsbl-phero .ph-rule{width:46px;height:2px;background:var(--accent);margin:0 0 16px}
.gtsbl-phero .ph-sub{margin:18px 0 0;max-width:440px;font-size:15px;font-weight:300;color:rgba(255,255,255,.92);line-height:1.55}
.gtsbl-phero.is-noimg{background:linear-gradient(120deg,#26231f 0%,#46403a 52%,#8a7e70 100%)}
@media(max-width:760px){.gtsbl-phero{min-height:320px}.gtsbl-phero-in{padding:0 22px 24px}}
/* "Fill to photo height" mode: show the photo at its natural proportions
   (full width, height auto) instead of cropping it to a fixed banner box.
   NOT capped (0.79.23). It used to be: max-height:min(900px,88vh) on a desktop
   and min(640px,80vh) on a phone, with overflow:hidden - so a portrait photo
   was CLIPPED past the cap. Measured on the KAO zone home at 1354px: the photo
   rendered 1474px tall inside a 698px box, so 53% of it was never visible.

   Troy's call: "we have a mode that says fill to photo height. That has got to
   happen - we can't cut off photos if that is selected." Correct, and the cap
   made the setting a half-truth. The box is now exactly the photo's height,
   always, at every width. If a hero comes out too tall for the page the answer
   is a wider photo, not a silent crop - and the image manager's mobile slot is
   there so a phone can have its own.

   overflow:hidden stays, for the rounded corners. With no cap there is nothing
   left for it to clip. */
.gtsbl-phero.is-natural{min-height:0;overflow:hidden}
.gtsbl-phero.is-natural .gtsbl-phero-img{position:static;display:block}
.gtsbl-phero.is-natural .gtsbl-phero-img img{position:static;width:100%;height:auto;object-fit:initial}
.gtsbl-phero.is-natural .gtsbl-phero-in{position:absolute;left:0;right:0;bottom:0;z-index:1}

/* ---- brand-home video hero ----
   Deliberately shares the .gtsbl-phero shell (same box, same gradient, same
   type scale) so a brand that turns the video hero on doesn't suddenly have a
   differently-shaped home page. What differs is the play affordance and what
   happens after it: mode D swaps the poster for the player in place, mode B
   leaves the poster over the player and fades it out. The mode classes below
   are the ONLY difference between them - see brandhome.php. */
.gtsbl-bhome{position:relative;border-radius:var(--r);overflow:hidden;min-height:460px;box-shadow:var(--sh);margin:18px 0 8px;background:#121418}
.gtsbl-bhome .bh-hero{position:relative;min-height:inherit;display:flex;align-items:flex-end}
.gtsbl-bhome .bh-img{position:absolute;inset:0}
.gtsbl-bhome .bh-img img{width:100%;height:100%;object-fit:cover;display:block}
.gtsbl-bhome .bh-hero::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,rgba(18,20,24,.68),rgba(18,20,24,.16) 42%,transparent 64%),linear-gradient(0deg,rgba(18,20,24,.55),transparent 46%)}
.gtsbl-bhome .bh-in{position:relative;z-index:1;width:100%;padding:0 36px 36px}
/* A's caption sits higher off the floor - it is the last thing read before the
   panel arrives, and text hard against the bottom edge reads as cut off. */
.gtsbl-bhome.is-a .bh-in{padding-bottom:110px}

/* Hero text at the TOP. The page header stack is ~400px tall, so on a
   screen-height hero a bottom-anchored caption begins below the fold and the
   brand's own word is never seen until the visitor scrolls. Top-positioning
   puts it in view at first paint. Set per brand in the page builder. */
.gtsbl-bhome.is-toptext .bh-hero{align-items:flex-start}
.gtsbl-bhome.is-toptext .bh-in{padding-top:38px;padding-bottom:0}
.gtsbl-bhome.is-a.is-toptext .bh-in{padding-bottom:0}
.gtsbl-bhome.is-natural.is-toptext .bh-in{top:0;bottom:auto}
.gtsbl-phero.is-toptext{align-items:flex-start}
.gtsbl-phero.is-toptext .gtsbl-phero-in{padding-top:38px;padding-bottom:0}
.gtsbl-phero.is-natural.is-toptext .gtsbl-phero-in{top:0;bottom:auto}
/* The scrim is bottom-weighted by default; flip it so top text stays legible. */
.gtsbl-bhome.is-toptext .bh-hero::after{background:linear-gradient(90deg,rgba(18,20,24,.68),rgba(18,20,24,.16) 42%,transparent 64%),linear-gradient(180deg,rgba(18,20,24,.55),transparent 46%)}
.gtsbl-phero.is-toptext::after{background:linear-gradient(90deg,rgba(18,20,24,.62),rgba(18,20,24,.12) 42%,transparent 64%),linear-gradient(180deg,rgba(18,20,24,.5),transparent 46%)}
.gtsbl-bhome .bh-eyebrow{display:block;font-size:12px;font-weight:600;letter-spacing:.22em;text-transform:uppercase;color:rgba(255,255,255,.85);margin-bottom:12px}
.gtsbl-bhome .bh-rule{width:46px;height:2px;background:var(--accent);margin:0 0 16px}
.gtsbl-bhome .bh-word{font-family:'DM Sans',sans-serif;font-weight:300;font-size:clamp(42px,7vw,88px);line-height:.95;letter-spacing:-.015em;color:#fff;margin:0;text-shadow:0 2px 26px rgba(0,0,0,.3)}
.gtsbl-bhome .bh-sub{margin:18px 0 0;max-width:440px;font-size:15px;font-weight:300;color:rgba(255,255,255,.92);line-height:1.55}
.gtsbl-bhome.is-noimg .bh-hero{background:linear-gradient(120deg,#26231f 0%,#46403a 52%,#8a7e70 100%)}

/* Play control. A pill, not a bare circle: the video's title is the promise
   being made, so it travels with the button rather than sitting elsewhere. */
.gtsbl-bhome .bh-play{display:inline-flex;align-items:center;gap:12px;margin:24px 0 0;padding:12px 22px 12px 14px;border:0;border-radius:40px;background:var(--accent);color:#fff;font:inherit;font-size:15px;font-weight:600;text-align:left;cursor:pointer;box-shadow:0 6px 24px rgba(0,0,0,.32);transition:transform var(--t),box-shadow var(--t),background var(--t)}
.gtsbl-bhome .bh-play:hover{transform:translateY(-1px);box-shadow:0 10px 30px rgba(0,0,0,.4)}
.gtsbl-bhome .bh-play:focus-visible{outline:3px solid #fff;outline-offset:3px}
.gtsbl-bhome .bh-play svg{width:26px;height:26px;flex:0 0 26px;fill:currentColor}
.gtsbl-bhome .bh-plabel{display:block;max-width:34ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gtsbl-bhome .bh-play.is-locked{background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.42);backdrop-filter:blur(3px);text-decoration:none;padding-left:22px}
.gtsbl-bhome .bh-play.is-locked:hover{background:rgba(255,255,255,.22)}
.gtsbl-bhome .bh-lockico{width:20px;height:20px;flex:0 0 20px;fill:none;stroke:currentColor;stroke-width:2}

/* The player. Empty and unstyled until JS puts an iframe in it, so an
   un-played hero costs nothing and leaves no gap. */
.gtsbl-bhome .bh-stage{display:none}
.gtsbl-bhome .bh-stage iframe{display:block;width:100%;height:100%;border:0}
.gtsbl-bhome.is-playing .bh-stage{display:block;position:relative;width:100%;aspect-ratio:16/9;background:#000}

/* D - the hero IS the video: poster out, player in, same box. */
.gtsbl-bhome.is-d.is-playing{min-height:0}
.gtsbl-bhome.is-d.is-playing .bh-hero{display:none}

/* B - play then fade: the player sits BEHIND the brand hero and the hero
   dissolves off it. The stage is absolute here and in flow in D - that, plus
   B showing the brand photo rather than the video frame, is the whole
   difference between the two modes. */
.gtsbl-bhome.is-b{min-height:min(78vh,760px)}
.gtsbl-bhome.is-b.is-playing .bh-stage{position:absolute;inset:0;aspect-ratio:auto;height:100%}
.gtsbl-bhome.is-b .bh-hero{transition:opacity .55s ease,visibility 0s linear .55s}
.gtsbl-bhome.is-b.is-playing .bh-hero{opacity:0;visibility:hidden;pointer-events:none}

/* A - scroll reveal: the hero fills the screen and STAYS while the player and
   the rail travel up over it. position:sticky does the whole job - no scroll
   listener, no transform maths, and it degrades to a normal hero wherever
   sticky is unsupported. The play control scrolls rather than swaps, because
   in this mode the reveal IS the interaction. */
/* The markup puts .bh-stage BEFORE .bh-hero (D swaps the hero out, so the
   player belongs first). A needs the opposite: the hero underneath, the player
   arriving over it. Flex order re-sequences them without a second template -
   the whole point of one renderer. */
.gtsbl-bhome.is-a{min-height:0;overflow:visible;background:none;box-shadow:none;border-radius:0}
.gtsbl-bhome.is-a .bh-hero{position:sticky;top:var(--gtsbl-navh,0px);height:calc(100vh - var(--gtsbl-navh,0px));min-height:0;border-radius:var(--r);overflow:hidden;box-shadow:var(--sh)}
/* CLEARANCE. The panel used to arrive the instant the hero reached the bottom
   of the screen, so the hero's own words were covered the moment they became
   readable. This gap means the hero is fully read - and stays clear - before
   anything slides over it. */
.gtsbl-bhome.is-a .bh-stage{position:relative;z-index:2;margin-top:120px;border-radius:var(--r);overflow:hidden;box-shadow:var(--sh)}
/* (no flex reordering: brandhome.php emits hero-before-stage for A, because a
   FLEX parent silently breaks position:sticky on the hero - measured on kao-d1,
   718/718/718 pinned with a block parent vs 574/374/174 never pinning in flex.) */
/* A's stage is visible from the start and holds the poster panel, so the
   sticky hero has real height to be revealed against. Without this the stage
   is display:none, the container is exactly as tall as the hero, and there is
   nowhere for it to stick - it just scrolls away like an ordinary hero. */
.gtsbl-bhome.is-a .bh-stage{display:block;aspect-ratio:16/9;background:#000;position:relative}
.gtsbl-bhome.is-a.is-playing .bh-stage{display:block;aspect-ratio:16/9;background:#000}
.gtsbl-bhome .bh-poster{display:block;position:absolute;inset:0;width:100%;height:100%;padding:0;border:0;background:#000;cursor:pointer;overflow:hidden}
.gtsbl-bhome .bh-poster img{width:100%;height:100%;object-fit:cover;display:block;opacity:.82;transition:opacity var(--t),transform var(--t)}
.gtsbl-bhome .bh-poster:hover img{opacity:1;transform:scale(1.02)}
.gtsbl-bhome .bh-poster:focus-visible{outline:3px solid #fff;outline-offset:-3px}
/* The non-A modes' poster is decoration, not a control - it holds the stage's
   size and keeps a black box from showing while the player loads. */
.gtsbl-bhome .bh-poster.is-static{cursor:default;pointer-events:none}
.gtsbl-bhome .bh-posterplay{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:76px;height:76px;border-radius:50%;background:var(--accent);display:flex;align-items:center;justify-content:center;box-shadow:0 10px 34px rgba(0,0,0,.5);transition:transform var(--t)}
.gtsbl-bhome .bh-poster:hover .bh-posterplay{transform:translate(-50%,-50%) scale(1.06)}
.gtsbl-bhome .bh-posterplay svg{width:34px;height:34px;fill:#fff}
.gtsbl-bhome .bh-postertitle{position:absolute;left:0;right:0;bottom:0;padding:44px 22px 18px;color:#fff;font-weight:600;font-size:16px;text-align:left;background:linear-gradient(0deg,rgba(0,0,0,.72),transparent)}
@media(prefers-reduced-motion:reduce){.gtsbl-bhome .bh-poster img,.gtsbl-bhome .bh-posterplay{transition:none}.gtsbl-bhome .bh-poster:hover img{transform:none}}
@media(max-width:760px){.gtsbl-bhome .bh-posterplay{width:60px;height:60px}.gtsbl-bhome .bh-posterplay svg{width:26px;height:26px}}
.gtsbl-bhome.is-a.is-playing .bh-hero{display:block}   /* the hero stays - that is the point */
@media(max-width:760px){.gtsbl-bhome.is-a .bh-hero{height:calc(82vh - var(--gtsbl-navh,0px))}}

/* A + natural height.
   A portrait photo cannot be BOTH fully visible AND pinned to a landscape
   screen - 2000x2400 in a ~1228x718 window either crops or letterboxes. That is
   geometry, not CSS, and no sticky rule solves it.
   So: pin a screen-height WINDOW (which sticks reliably) and pan the full-height
   photo through it as you scroll. The whole image is seen, the hero stays put,
   and the player still rises over it. The pan is driven by JS in brandhome.php.
   Bottom-sticky on the tall element itself was tried and measured - it does not
   pin here regardless of parent display or DOM order. */
.gtsbl-bhome.is-a.is-natural{max-height:none;overflow:visible}
.gtsbl-bhome.is-a.is-natural .bh-hero{position:sticky;top:var(--gtsbl-navh,0px);height:calc(100vh - var(--gtsbl-navh,0px));min-height:0;display:block;border-radius:var(--r);overflow:hidden;box-shadow:var(--sh)}
.gtsbl-bhome.is-a.is-natural .bh-img{position:absolute;left:0;right:0;top:0;display:block;will-change:transform}
.gtsbl-bhome.is-a.is-natural .bh-img img{position:static;width:100%;height:auto;object-fit:initial;display:block}
.gtsbl-bhome.is-a.is-natural .bh-in{position:absolute;left:0;right:0;bottom:0;padding-bottom:110px;z-index:1}
@media(prefers-reduced-motion:reduce){.gtsbl-bhome.is-a.is-natural .bh-img{transition:none}}

/* C - two pages: the landing is a full screen with one way forward. No rail
   below it, because portal.php suppresses the listing while landing. */
.gtsbl-bhome.is-c{min-height:min(84vh,860px)}
.gtsbl-bhome.is-c .bh-hero{min-height:inherit}
/* C HAD NO is-playing RULES AT ALL (0.79.31). D hides its hero and drops its
   min-height when the player arrives; B fades its hero out; A keeps its hero on
   purpose. C was simply never given an answer, so the player appeared and the
   brand hero stayed sitting underneath it - Troy: "the player comes up but I see
   the hero under the player" - inside a box still holding its 84vh landing
   height. It behaves like D from here: the player replaces the hero. */
.gtsbl-bhome.is-c.is-playing{min-height:0}
.gtsbl-bhome.is-c.is-playing .bh-hero{display:none}
.gtsbl-bhome .bh-enter{text-decoration:none}
.gtsbl-bhome .bh-enter svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}
/* "Enter" must never ellipsis (0.79.31). Troy saw it as "En...".
   max-width:none was already here and is not enough on its own: .bh-plabel also
   carries overflow:hidden + text-overflow:ellipsis, so the moment anything
   squeezes the BUTTON - a narrow column, a flex parent, a phone - the word gets
   cut regardless of its max-width. The label of a one-word control has nothing
   to gain from truncation, so it opts out of the mechanism entirely, and the
   button refuses to be shrunk below its content. */
.gtsbl-bhome .bh-enter{flex:0 0 auto}
.gtsbl-bhome .bh-enter .bh-plabel{max-width:none;overflow:visible;text-overflow:clip;min-width:max-content}

/* "Fill to photo height" from the page builder, for the modes that show the
   BRAND photo (A, B, C). Same rule the editorial hero uses: show the photo at
   its own proportions, capped so a portrait shot cannot take over the page. */
/* Cap REMOVED in 0.79.23. It went min(900px,88vh) -> min(1500px,145vh) -> gone,
   which is the whole story: every time the cap was raised it was because a real
   photo had been cut off by it, and a cap that has to keep moving to stop
   cutting photos off is a cap that should not exist. Troy: "we have a mode that
   says fill to photo height. That has got to happen - we can't cut off photos
   if that is selected." Measured on kao-d2 at 1354px before this change: photo
   1474px tall, box clipped to 1150px, 324px hidden.

   Mode A is deliberately NOT included in this. Its window is 100vh and the
   photo is PANNED through it on scroll, so the whole photo is seen - nothing is
   cut off there, and removing that window would delete the mode. */
.gtsbl-bhome.is-natural{min-height:0;overflow:hidden}
/* .bh-hero goes STATIC here so the caption anchors to the outer box rather than
   to the photo. This mattered enormously while the box clipped (an inner
   anchored to a 1474px photo inside a 632px box put the title and play button
   840px below the visible area - rendered, focusable, completely invisible;
   measured on kao-d1). With the cap gone the two heights are the same, so it is
   now belt and braces rather than the fix - keep it: hero_fit can change per
   brand, and .is-natural is not the only thing that sets this box's height. */
.gtsbl-bhome.is-natural .bh-hero{min-height:0;position:static;display:block}
.gtsbl-bhome.is-natural .bh-img{position:static;display:block}
.gtsbl-bhome.is-natural .bh-img img{position:static;width:100%;height:auto;object-fit:initial}
.gtsbl-bhome.is-natural .bh-in{position:absolute;left:0;right:0;bottom:0;z-index:1}
/* The phone cap (max-height:min(900px,110vh)) went with the desktop one in
   0.79.23 - a phone is where a cut-off photo shows most, not least. */
@media(max-width:760px){.gtsbl-bhome.is-a .bh-stage{margin-top:80px}.gtsbl-bhome.is-a .bh-in{padding-bottom:60px}}
@media(prefers-reduced-motion:reduce){.gtsbl-bhome.is-b .bh-hero{transition:none}.gtsbl-bhome .bh-play{transition:none}.gtsbl-bhome .bh-play:hover{transform:none}}

/* ---- watch-next card ----
   Standalone on purpose: it appears over the brand-home hero AND over the
   player on an AVS video page, so it must not depend on being inside either.
   It fills whatever POSITIONED box it is dropped into.

   Cancel is the calmer of the two actions but is NOT a whisper - the countdown
   is about to act on its own, so the way out has to be as easy to hit as the
   way forward. */
.gtsbl-wnext{position:absolute;inset:0;z-index:3;display:flex;align-items:center;justify-content:center;padding:20px;background:rgba(12,14,17,.82);backdrop-filter:blur(6px)}
.gtsbl-wnext[hidden]{display:none}
.gtsbl-wnext .wn-in{width:min(440px,100%);background:rgba(24,27,32,.94);border:1px solid rgba(255,255,255,.14);border-radius:var(--rb);padding:20px;box-shadow:0 24px 60px rgba(0,0,0,.5)}
.gtsbl-wnext .wn-k{display:block;font-size:11px;font-weight:600;letter-spacing:.2em;text-transform:uppercase;color:rgba(255,255,255,.62);margin-bottom:12px}
.gtsbl-wnext .wn-row{display:flex;gap:13px;align-items:flex-start}
.gtsbl-wnext .wn-th{width:132px;flex:0 0 132px;aspect-ratio:16/9;object-fit:cover;border-radius:var(--rs);background:#000;display:block}
.gtsbl-wnext .wn-meta{min-width:0}
.gtsbl-wnext .wn-t{margin:0 0 5px;font-size:15px;font-weight:600;line-height:1.3;color:#fff;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.gtsbl-wnext .wn-c{margin:0;font-size:13px;color:rgba(255,255,255,.7)}
.gtsbl-wnext .wn-acts{display:flex;gap:9px;margin-top:17px}
.gtsbl-wnext .wn-b{flex:1;padding:11px 14px;border-radius:9px;font:inherit;font-size:14px;font-weight:600;cursor:pointer;border:1px solid transparent;transition:background var(--t),border-color var(--t)}
.gtsbl-wnext .wn-b:focus-visible{outline:3px solid #fff;outline-offset:2px}
.gtsbl-wnext .wn-b.is-cancel{background:transparent;border-color:rgba(255,255,255,.34);color:#fff}
.gtsbl-wnext .wn-b.is-cancel:hover{background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.5)}
.gtsbl-wnext .wn-b.is-go{background:var(--accent);color:#fff}
.gtsbl-wnext .wn-b.is-go:hover{filter:brightness(1.08)}
/* The card needs a positioned ancestor to fill. The hero already is one; the
   AVS player wrapper is not, so our override adds this class to it. */
.gtsbl-playerwrap{position:relative}
/* Mode D collapses the hero box to the stage while playing, so the card needs
   the stage's height to sit over. */
.gtsbl-bhome.is-d.is-next{min-height:0}
@media(max-width:760px){.gtsbl-wnext .wn-in{padding:16px}.gtsbl-wnext .wn-th{width:96px;flex:0 0 96px}.gtsbl-wnext .wn-acts{margin-top:14px}}
@media(max-width:760px){.gtsbl-bhome{min-height:340px}.gtsbl-bhome .bh-in{padding:0 22px 24px}.gtsbl-bhome .bh-play{padding:11px 18px 11px 12px;font-size:14px}.gtsbl-bhome .bh-plabel{max-width:20ch}}
.gtsbl-zheroimg img{display:block;width:100%;height:auto;border-radius:var(--r);box-shadow:var(--sh)}
.gtsbl-acctbanner{margin:0 0 20px}
.gtsbl-acctbanner .gtsbl-zbanner{margin-top:0}
.gtsbl-banner + .gtsbl-zhero{padding-top:30px}
.gtsbl-banner-inner{margin-top:22px;margin-bottom:8px;height:230px}
@media(max-width:760px){.gtsbl-banner{height:auto;aspect-ratio:var(--ar-m,16/6);background-image:var(--img-m,var(--img-d));background-size:contain;background-repeat:no-repeat;background-color:var(--surf2)}.gtsbl-banner-inner{height:auto;aspect-ratio:var(--ar-m,16/5)}}

/* video-page brand category menu */
.gtsbl-catmenu{display:flex;flex-wrap:wrap;gap:8px;margin:18px 0 4px}
.gtsbl-catmenu .cm-i{display:inline-flex;align-items:center;gap:7px;padding:8px 14px;border-radius:22px;border:1px solid var(--bdr);background:var(--surf);color:var(--txt2);font-weight:600;font-size:13.5px;transition:background var(--t),color var(--t),border-color var(--t)}
.gtsbl-catmenu .cm-i:hover{color:var(--txt);border-color:var(--bdr2)}
.gtsbl-catmenu .cm-i.is-active{background:var(--accent);border-color:var(--accent);color:#fff}
.gtsbl-catmenu .cm-i.is-locked{opacity:.85}
.gtsbl-catmenu .cm-lock svg{width:12px;height:12px;stroke:currentColor}
/* video-page brand block */
.gtsbl-vbrand .gtsbl-bcard{max-width:520px;aspect-ratio:16/10}

/* ---- bigger KAO (zone) wordmark in the nav ---- */
body.is-zone-home .gtsbl-nav .nm-logo,body.is-account .gtsbl-nav .nm-logo{height:52px;max-width:190px}
@media(max-width:760px){body.is-zone-home .gtsbl-nav .nm-logo,body.is-account .gtsbl-nav .nm-logo{height:42px}}

/* admin console link in brand nav (GTS-Admin only) - matches the user bubble */
.gtsbl-admin{display:inline-flex;align-items:center;gap:8px;font-weight:600;font-size:13.5px;
  color:var(--txt2);background:var(--surf);border:1px solid var(--bdr);
  min-height:46px;padding:0 16px;border-radius:30px;transition:border-color var(--t,.2s ease),box-shadow var(--t,.2s ease),color var(--t,.2s ease)}
.gtsbl-admin:hover{color:var(--txt);border-color:var(--bdr2);box-shadow:var(--sh)}
.gtsbl-admin svg{width:16px;height:16px;stroke:var(--accent)}
@media(max-width:760px){.gtsbl-admin{font-size:0;gap:0;min-height:0;width:42px;height:42px;padding:0;justify-content:center;border-radius:50%}.gtsbl-admin svg{width:18px;height:18px}}

/* the category's own videos, below the player (single-video page). Was a rail
   until 0.79.40; it is the same .vgrid the category page uses now. */
.gtsbl .gtsbl-related{margin-top:18px;padding-top:22px;border-top:1px solid var(--bdr)}
.gtsbl .gtsbl-related-empty{color:var(--txt3);font-size:14px;padding:4px 2px 10px}
/* The card for the video you are already watching. It stays in the grid so the
   count matches the category page, but it must not read as somewhere to go. */
.gtsbl .vc.is-playing{cursor:default;pointer-events:none}
.gtsbl .vc.is-playing .vc-thumb{outline:2px solid var(--accent);outline-offset:2px;filter:saturate(.6) brightness(.72)}
.gtsbl .vc.is-playing .vc-m{color:var(--accent);font-weight:600}
/* The tile for the category you are already in. Same rule as .is-playing: it
   stays in the row so the count never changes, but it is not a door. */
.gtsbl .cat.is-current{cursor:default;pointer-events:none}
.gtsbl .cat.is-current .bg{filter:saturate(.55) brightness(.6)}
.gtsbl .cat.is-current::after{content:"";position:absolute;inset:0;border:2px solid var(--accent);border-radius:inherit;pointer-events:none}
.gtsbl .cat.is-current .lbl span{color:var(--accent);font-weight:600}

/* ============================================================
   ACCOUNT AREA  ·  user bubble + dropdown, shell, auth, cards
   ============================================================ */
/* user bubble + dropdown (header) */
.gtsbl-nav .gtsbl-usr{position:relative}
.gtsbl-usr-btn{display:flex;align-items:center;gap:9px;padding:5px 12px 5px 5px;border-radius:30px;border:1px solid var(--bdr);background:var(--surf);color:var(--txt);cursor:pointer;font-family:var(--f-body);transition:border-color var(--t),box-shadow var(--t)}
.gtsbl-usr-btn:hover{border-color:var(--bdr2);box-shadow:var(--sh)}
.gtsbl-usr-av{width:34px;height:34px;border-radius:50%;background:linear-gradient(135deg,var(--accent),var(--brand-2));color:#fff;font-family:var(--f-disp);font-weight:600;font-size:13.5px;display:flex;align-items:center;justify-content:center;flex-shrink:0;letter-spacing:.02em}
.gtsbl-usr-av.lg{width:46px;height:46px;font-size:17px;border-radius:14px}
.gtsbl-usr-nm{font-weight:600;font-size:14px;line-height:1;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gtsbl-usr-cv{width:16px;height:16px;stroke:var(--txt3);transition:transform var(--t)}
.gtsbl-usr.open .gtsbl-usr-cv{transform:rotate(180deg)}
.gtsbl-usr-menu{position:absolute;top:calc(100% + 10px);right:0;width:290px;background:var(--surf);border:1px solid var(--bdr);border-radius:var(--r);box-shadow:var(--sh);padding:8px;opacity:0;visibility:hidden;transform:translateY(-6px);transition:opacity var(--t),transform var(--t),visibility var(--t);z-index:90}
.gtsbl-usr.open .gtsbl-usr-menu{opacity:1;visibility:visible;transform:translateY(0)}
.gtsbl-usr-head{display:flex;align-items:center;gap:12px;padding:10px 10px 12px}
.gtsbl-usr-id{min-width:0}
.gtsbl-usr-hn{font-family:var(--f-disp);font-weight:600;font-size:15px;display:block;line-height:1.2}
.gtsbl-usr-he{font-size:12px;color:var(--txt3);display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gtsbl-usr-sep{height:1px;background:var(--bdr);margin:6px 4px}
.gtsbl-usr-i{display:flex;align-items:center;gap:11px;padding:9px 11px;border-radius:9px;color:var(--txt2);font-weight:500;font-size:14px;cursor:pointer}
.gtsbl-usr-i svg{width:17px;height:17px;stroke:currentColor;flex-shrink:0}
.gtsbl-usr-i:hover{background:var(--surf2);color:var(--txt)}
.gtsbl-usr-i.out{color:var(--red,#d9483b)}
.gtsbl-usr-i.out:hover{background:color-mix(in srgb,var(--red,#d9483b) 12%,transparent)}
@media(max-width:760px){.gtsbl-usr-nm{display:none}}

/* account shell */
.gtsbl-acctshell{display:grid;grid-template-columns:248px 1fr;gap:26px;margin-top:26px;align-items:start}
.gtsbl-aside{background:var(--surf);border:1px solid var(--bdr);border-radius:var(--r);padding:16px;position:sticky;top:88px}
.gtsbl-aside-id{display:flex;align-items:center;gap:12px;padding:6px 6px 16px;border-bottom:1px solid var(--bdr);margin-bottom:12px}
.gtsbl-aside-id .nm{font-family:var(--f-disp);font-weight:600;font-size:15px;line-height:1.2}
.gtsbl-aside-id .rl{font-size:11.5px;color:var(--txt3)}
.gtsbl-aside-nav{display:flex;flex-direction:column;gap:3px}
.gtsbl-aside-nav .an-i{display:flex;align-items:center;gap:11px;padding:10px 11px;border-radius:9px;color:var(--txt2);font-weight:500;font-size:14px;cursor:pointer;position:relative}
.gtsbl-aside-nav .an-i svg{width:17px;height:17px;stroke:currentColor;flex-shrink:0}
.gtsbl-aside-nav .an-i:hover{background:var(--surf2);color:var(--txt)}
.gtsbl-aside-nav .an-i.active{background:color-mix(in srgb,var(--accent) 13%,transparent);color:var(--accent);font-weight:600}
.gtsbl-aside-nav .an-i.active::before{content:"";position:absolute;left:-16px;top:9px;bottom:9px;width:3px;border-radius:0 3px 3px 0;background:var(--accent)}
.gtsbl-aside-nav .an-i .tag{margin-left:auto;font-family:var(--f-mono);font-size:9.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--accent);background:color-mix(in srgb,var(--accent) 14%,transparent);padding:2px 7px;border-radius:10px}
.gtsbl-aside-foot{margin-top:14px;padding-top:14px;border-top:1px solid var(--bdr);font-size:11.5px;color:var(--txt3)}
.gtsbl-acctmain{min-width:0}

/* auth card (guest) */
.gtsbl-authwrap{display:flex;justify-content:center;padding:40px 0 60px}
.gtsbl-authcard{width:100%;max-width:440px;background:var(--surf);border:1px solid var(--bdr);border-radius:var(--r);box-shadow:var(--sh);overflow:hidden}
.gtsbl-auth-tabs{display:flex}
.gtsbl-auth-tab{flex:1 1 0;text-align:center;padding:16px 10px;font-family:var(--f-body);font-weight:600;font-size:14.5px;color:var(--txt2);background:var(--surf2);border-bottom:1px solid var(--bdr);transition:color var(--t),background var(--t)}
.gtsbl-auth-tab:hover{color:var(--txt)}
.gtsbl-auth-tab.active{color:var(--txt);background:var(--surf);border-bottom:2px solid var(--accent)}
.gtsbl-auth-head{padding:28px 30px 6px;text-align:center}
.gtsbl-auth-head h1{font-family:var(--f-disp);font-weight:600;font-size:26px;margin:8px 0 6px}
.gtsbl-auth-head p{color:var(--txt2);font-size:14px}
.gtsbl-auth-body{padding:18px 30px 30px}
/* Joomla's stock login layout prints "Don't have an account?" below the
   form - redundant now that the Sign Up tab above does that job. The
   Forgot password/username links right next to it are left untouched. */
.gtsbl-auth-body.has-tabs .com-users-login__register{display:none}

/* page head + cards */
.gtsbl-page-head{margin-bottom:20px}
.gtsbl-page-head h1{font-family:var(--f-disp);font-weight:600;font-size:28px;letter-spacing:-.01em}
.gtsbl-page-head p{color:var(--txt2);font-size:14.5px;margin-top:5px}
.gtsbl-card{background:var(--surf);border:1px solid var(--bdr);border-radius:var(--r);padding:20px;box-shadow:var(--sh)}
.gtsbl-card+.gtsbl-card{margin-top:18px}
.gtsbl-card .card-h{display:flex;align-items:center;gap:10px;margin-bottom:14px}
.gtsbl-card .card-h h2{font-family:var(--f-disp);font-weight:600;font-size:17px}
.gtsbl-card .card-h .soon{margin-left:auto;font-family:var(--f-mono);font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--txt3);background:var(--surf2);border:1px solid var(--bdr);padding:3px 9px;border-radius:20px}
.gtsbl-card .card-lead{color:var(--txt2);font-size:13.5px;margin:-6px 0 14px}

/* plan banner */
.gtsbl-plan{display:flex;align-items:center;gap:18px;background:linear-gradient(120deg,var(--brand-2),var(--accent));color:#fff;border-radius:var(--r);padding:22px 24px;box-shadow:var(--sh);position:relative;overflow:hidden;margin-bottom:18px}
.gtsbl-plan::after{content:"";position:absolute;right:-40px;top:-40px;width:180px;height:180px;border-radius:50%;background:rgba(255,255,255,.12);pointer-events:none}
.gtsbl-plan .pi{position:relative}
.gtsbl-plan .pe{font-family:var(--f-mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;opacity:.85}
.gtsbl-plan h2{font-family:var(--f-disp);font-weight:600;font-size:22px;margin-top:4px}
.gtsbl-plan .pp{font-family:var(--f-mono);font-size:13px;font-weight:400;opacity:.82;margin-left:4px}
.gtsbl-plan p{font-size:13px;opacity:.92;margin-top:4px;max-width:520px}
.gtsbl-plan .pr{position:relative;margin-left:auto;display:flex;gap:10px}
.gtsbl-plan .btn-w{background:#fff;color:#111;border:0;font-weight:600;font-size:13.5px;padding:11px 18px;border-radius:30px;cursor:pointer;white-space:nowrap}
.gtsbl-plan .btn-g{background:rgba(255,255,255,.16);color:#fff;border:1px solid rgba(255,255,255,.3);font-weight:600;font-size:13.5px;padding:11px 18px;border-radius:30px;cursor:pointer;white-space:nowrap}

/* brand chips */
.gtsbl-chips{display:flex;gap:10px;flex-wrap:wrap}
.gtsbl-chip{display:flex;align-items:center;gap:9px;border:1px solid var(--bdr);border-radius:30px;padding:8px 8px 8px 8px;background:var(--surf2);font-weight:600;font-size:13.5px;color:var(--txt);transition:border-color var(--t),transform var(--t)}
.gtsbl-chip:hover{border-color:var(--bdr2);transform:translateY(-1px)}
.gtsbl-chip .cd{width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:#fff;font-family:var(--f-disp);font-size:11px;font-weight:600}
.gtsbl-chip[data-c="goldwell"] .cd{background:#c89a3c}.gtsbl-chip[data-c="kms"] .cd{background:#e8472d}.gtsbl-chip[data-c="kerasilk"] .cd{background:#a8678c}
.gtsbl-chip .ar{color:var(--txt3);margin:0 6px 0 2px;font-size:15px}

/* empty states */
.gtsbl-empty{text-align:center;padding:26px 20px;color:var(--txt3)}
.gtsbl-empty svg{width:34px;height:34px;stroke:var(--txt3);margin:0 auto 12px;opacity:.8}
.gtsbl-empty b{display:block;color:var(--txt2);font-size:14px;font-weight:600}
.gtsbl-empty span{display:block;font-size:12.5px;margin-top:5px;max-width:380px;margin-left:auto;margin-right:auto;line-height:1.5}

/* profile header + meta */
.gtsbl-prof-top{display:flex;align-items:center;gap:18px}
.gtsbl-prof-av{width:64px;height:64px;border-radius:18px;background:linear-gradient(135deg,var(--accent),var(--brand-2));color:#fff;font-family:var(--f-disp);font-weight:600;font-size:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.gtsbl-prof-id{flex:1;min-width:0}
.gtsbl-prof-id .pn{font-family:var(--f-disp);font-weight:600;font-size:20px}
.gtsbl-prof-id .ps{color:var(--txt2);font-size:13.5px;margin-top:3px}
.gtsbl-meta{display:grid;grid-template-columns:auto 1fr;gap:8px 18px;align-items:center}
.gtsbl-meta .k{color:var(--txt3);font-size:12.5px}
.gtsbl-meta .v{color:var(--txt);font-weight:500;font-size:13.5px;text-align:right}

/* account buttons */
.gtsbl-acctmain .btn{font-family:var(--f-body);font-weight:600;font-size:13.5px;padding:10px 16px;border-radius:9px;border:1px solid var(--bdr2);background:var(--surf2);color:var(--txt);cursor:pointer;display:inline-flex;align-items:center;gap:8px;text-decoration:none}
.gtsbl-acctmain .btn svg{width:15px;height:15px;stroke:currentColor}
.gtsbl-acctmain .btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}
.gtsbl-acctmain .btn.primary svg{stroke:#fff}

/* style the real com_users component (login/profile/edit forms) */
.gtsbl-acctcomp,.gtsbl-auth-body{font-size:14px}
.gtsbl-acctcomp input:not([type=checkbox]):not([type=radio]):not([type=submit]),.gtsbl-acctcomp select,
.gtsbl-auth-body input:not([type=checkbox]):not([type=radio]):not([type=submit]),.gtsbl-auth-body select{width:100%;font-family:var(--f-body);font-size:14px;color:var(--txt);background:var(--surf2);border:1px solid var(--bdr2);border-radius:9px;padding:11px 13px;outline:none;transition:border-color var(--t);margin-bottom:4px}
.gtsbl-acctcomp input:focus,.gtsbl-acctcomp select:focus,.gtsbl-auth-body input:focus,.gtsbl-auth-body select:focus{border-color:var(--accent)}
.gtsbl-acctcomp label,.gtsbl-auth-body label{font-size:12.5px;font-weight:600;color:var(--txt2);display:inline-block;margin-bottom:4px}
.gtsbl-acctcomp .control-group,.gtsbl-auth-body .control-group{margin-bottom:11px}
.gtsbl-acctcomp .controls,.gtsbl-auth-body .controls{margin-top:2px}
/* Joomla core wraps the whole registration form in .com-users-registration
   with a hardcoded 40px top / 60px bottom margin (confirmed via Chrome
   devtools) - that's the big gap under "Create your account" before the
   form box, plus extra dead space below it. Collapse both down. */
.gtsbl-auth-body .com-users-registration{margin-top:0!important;margin-bottom:0!important}
/* "* Required field" spacer row - just a caption, not a real field */
.gtsbl-auth-body .control-group.field-spacer{margin-bottom:4px}
.gtsbl-auth-body .control-group.field-spacer label{font-size:11px;font-weight:500;color:var(--txt3);margin-bottom:0}
/* password strength requirements caption above the password field */
.gtsbl-auth-body [id$="-rules"]{font-size:11px;line-height:1.4;color:var(--txt3);margin-bottom:5px}
/* Password input + show/hide toggle share ONE row, split ~80/20. The
   toggle has no icon font in this template (falls back to its visually-
   hidden label text), so at 20% width the words "Show Password" don't fit
   on one line - stack them instead of shrinking to the point of being
   unreadable. */
/* align-items:center (not stretch) + an explicit matching height on both
   the input and the toggle - stretch was letting the toggle's 2-line text
   content dictate the row height, making it taller than the input. Fixed
   height on both guarantees they match; overflow:hidden on the toggle clips
   instead of growing if the text doesn't quite fit. */
.gtsbl-auth-body .password-group .input-group{display:flex;align-items:center;gap:6px}
/* !important on margin-bottom only: confirmed via devtools that the input
   and toggle were both 42px tall (correct) but sat 2px apart vertically -
   the generic input rule's :not()-chain selector has higher specificity
   than this one even though this is more specific-looking, so its
   margin-bottom:4px was winning and effectively adding 4px to the input's
   flex-item box, throwing off centering against the toggle beside it. */
.gtsbl-auth-body .password-group input{flex:1 1 auto;min-width:0;width:auto;height:42px;margin-bottom:0!important}
/* NOTE: selector is 3 classes deep (not 2) on purpose - the generic
   `.gtsbl-auth-body .btn` rule further down this file has the same
   specificity as a plain `.gtsbl-auth-body .input-password-toggle` would,
   and being LATER in the file it was winning the cascade tiebreak and
   silently overriding font-size back to 14px. The extra `.password-group`
   ancestor makes this selector unambiguously more specific so it always wins
   regardless of source order. Font confirmed via Troy's own testing: 11px. */
.gtsbl-auth-body .password-group .input-password-toggle{flex:0 0 20%;min-width:60px;height:42px;box-sizing:border-box;overflow:hidden;padding:2px;font-size:11px;line-height:1.15;white-space:normal;text-align:center;display:flex;align-items:center;justify-content:center;margin-bottom:0;gap:0}
/* The button's icon span (.icon-eye) is empty/invisible (no icon font loaded
   in this template) and measures 0px wide - but the generic .gtsbl-main .btn
   rule sets flex gap:8px between a button's children, so that empty icon
   still reserved an 8px gap before the visible "Show Password" text,
   shifting the text ~4px right of the button's true center. gap:0 here
   (same 3-class-deep specificity as the rule above, so it always wins)
   removes that phantom reserved space so justify-content:center actually
   centers the text itself. Confirmed via live devtools measurement. */
.gtsbl-auth-body .password-group .input-password-toggle .icon-eye{display:none}
/* native <meter> strength bar + its status label, inserted by Joomla core's
   passwordstrength.js right after each password field - own quiet row
   below the input+toggle row, doubled in height per feedback. */
.gtsbl-auth-body .password-group meter{display:block;width:100%;height:10px;margin:6px 0 2px;border-radius:4px;overflow:hidden}
.gtsbl-auth-body .password-group meter::-webkit-meter-bar{background:var(--surf2);border-radius:4px;border:none;height:10px}
/* Registration form: Email moved above the password fields (Joomla core's
   field order is Name/Username/Password/Confirm/Email - can't reorder the
   actual markup since it's core output, so this reorders visually via flex
   + explicit order, matched by each field's stable Joomla-assigned id). */
.gtsbl-auth-body #member-registration fieldset{display:flex;flex-direction:column}
.gtsbl-auth-body #member-registration fieldset .control-group.field-spacer{order:1}
.gtsbl-auth-body #member-registration fieldset .control-group:has(#jform_name){order:2}
.gtsbl-auth-body #member-registration fieldset .control-group:has(#jform_username){order:3}
.gtsbl-auth-body #member-registration fieldset .control-group:has(#jform_email1){order:4}
.gtsbl-auth-body #member-registration fieldset .control-group:has(#jform_password1){order:5}
.gtsbl-auth-body #member-registration fieldset .control-group:has(#jform_password2){order:6}
.gtsbl-auth-body .password-group .text-center{font-size:11px;color:var(--txt3);min-height:14px;margin:0;text-align:left}
.gtsbl-acctcomp dl,.gtsbl-acctcomp dd{margin:0}
.gtsbl-acctcomp dt{font-size:12px;color:var(--txt3);margin-top:12px;font-weight:600}
.gtsbl-acctcomp dd{font-size:14px;color:var(--txt);padding-bottom:8px;border-bottom:1px solid var(--bdr)}
.gtsbl-acctcomp .btn,.gtsbl-auth-body .btn,.gtsbl-acctcomp button[type=submit],.gtsbl-auth-body button[type=submit]{font-family:var(--f-body);font-weight:600;font-size:14px;padding:11px 18px;border-radius:9px;border:1px solid var(--bdr2);background:var(--surf2);color:var(--txt);cursor:pointer}
.gtsbl-acctcomp .btn-primary,.gtsbl-auth-body .btn-primary,.gtsbl-auth-body button[type=submit]{background:var(--accent);border-color:var(--accent);color:#fff;width:100%;justify-content:center}
.gtsbl-auth-body .btn-primary:hover,.gtsbl-auth-body button[type=submit]:hover{filter:brightness(1.06)}
.gtsbl-auth-body nav ul,.gtsbl-auth-body ul.nav{list-style:none;padding:0;margin:14px 0 0;display:flex;flex-direction:column;gap:6px;text-align:center}
.gtsbl-auth-body nav a{color:var(--accent);font-size:13px;font-weight:600}

@media(max-width:880px){.gtsbl-acctshell{grid-template-columns:1fr}.gtsbl-aside{position:static}.gtsbl-plan{flex-direction:column;align-items:flex-start;gap:14px}.gtsbl-plan .pr{margin-left:0}}

/* account profile detail list + edit-form sections */
.gtsbl-deflist .drow{display:flex;justify-content:space-between;gap:16px;padding:12px 0;border-top:1px solid var(--bdr)}
.gtsbl-deflist .drow:first-child{border-top:0}
.gtsbl-deflist .drow .k{color:var(--txt3);font-size:13px}
.gtsbl-deflist .drow .v{color:var(--txt);font-weight:500;font-size:14px;text-align:right;word-break:break-word}
.gtsbl-acctedit fieldset{border:0;padding:0;margin:0 0 22px;min-width:0}
.gtsbl-acctedit legend{font-family:var(--f-disp);font-weight:600;font-size:16px;color:var(--txt);padding:0 0 10px;margin:0 0 14px;border-bottom:1px solid var(--bdr);width:100%}
.gtsbl-acctedit dl.dl-horizontal,.gtsbl-acctedit dt,.gtsbl-acctedit dd{margin:0}

/* hero/zhero headline sizes must outrank .gtsbl-main h1 (same specificity, so scoped + last) */
@media(max-width:760px){.gtsbl-main .gtsbl-hero h1{font-size:32px}.gtsbl-main .gtsbl-zhero h1{font-size:34px}}

/* ===== KAO Education cross-site promo strip ===== */
.gtsbl-edubar{background:linear-gradient(120deg,#6f93b8 0%,#16263a 92%);color:#eaf2fb}
.gtsbl-edubar .edubar-in{display:flex;align-items:center;gap:14px;padding-top:11px;padding-bottom:11px}
.gtsbl-edubar .eb-tag{font-family:'DM Sans',sans-serif;font-weight:700;font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;background:rgba(255,255,255,.16);color:#fff;padding:3px 9px;border-radius:30px}
.gtsbl-edubar .eb-msg{font-size:13px;font-weight:500;letter-spacing:.01em;color:#eef5fc}
.gtsbl-edubar .eb-msg strong{font-weight:800}
.gtsbl-edubar .eb-go{margin-left:auto;display:inline-flex;align-items:center;gap:9px;font-weight:800;font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:#fff;white-space:nowrap}
.gtsbl-edubar .eb-go svg{width:22px;height:9px;stroke:currentColor}
.gtsbl-edubar .eb-go:hover{color:#dbe9f7}
@media(max-width:760px){.gtsbl-edubar .eb-tag{display:none}.gtsbl-edubar .eb-msg{font-size:12px}}

/* ===== Full-screen LiveKit meeting room (is-room) ===== */
body.is-room{background:#0e1117;margin:0}
body.is-room .gtsroom-stage{min-height:100vh;width:100%}

@media(max-width:760px){
  .gtsbl-brandbar .bb-home span,.gtsbl-brandbar .bb-classes span{display:none}
  .gtsbl-brandbar .bb-home,.gtsbl-brandbar .bb-classes{padding:9px 12px;gap:0}
  .gtsbl-brandbar .bb-home svg,.gtsbl-brandbar .bb-classes svg{width:17px;height:17px}
  .gtsbl-brandbar .bb-div{margin:0 2px}
}

/* ===================== GTS toasts (system messages) =====================
   Floating message bar, fixed to the top of the viewport above everything.

   Joomla's messages used to render in the flow of the content column. Moving
   them above the page body was necessary but not sufficient: the login form is
   vertically centred, so a message at the top of the column is still off
   screen and a failed sign-in looks like nothing happened. These sit over the
   page instead, where the eye already is.

   Styled so the RAW Joomla markup inside #gtsblToasts is legible too - with
   JavaScript off there is no auto-dismiss, but the message is still visible.
   =====================================================================  */

.gtsbl-toasts {
    position: fixed;
    top: 14px;
    /* PINNED TO BOTH EDGES, not sized off the viewport (0.79.25).
       It used to be `left:50%; transform:translateX(-50%);
       width:min(560px, calc(100vw - 24px))`, and Troy saw it overhang his
       iPhone and drag the page wider than the screen.

       100vw is not reliably the width of the phone. If ANY element on the page
       sticks out past the right edge, iOS Safari widens the layout viewport so
       that element fits, and from then on 100vw reports the wider number. The
       bar sized itself to that, became wider than the screen, and - being
       centred by a negative half-width transform - hung off BOTH sides, which
       kept the page wide. A loop that feeds itself.

       Pinning left AND right removes the measurement entirely: the bar is
       whatever fits between the two insets, so it cannot be wider than the
       screen no matter what 100vw claims. max-width keeps the desktop size and
       margin-inline:auto re-centres it once max-width bites. */
    left: 12px;
    right: 12px;
    width: auto;
    max-width: 560px;
    margin-inline: auto;
    /* Above the console shell and the upgrade modal, which were the previous
       highest things on the page. */
    z-index: 100000;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;   /* the page stays clickable around the toasts */
}

/* Kept for the case where the host genuinely has no children. It does NOT fire
   in normal use: Joomla always emits #system-message-container inside the host,
   message or not, so the host is never :empty. That is exactly the trap 0.62.0
   fell into - see the fallback rule below. */
.gtsbl-toasts:empty { display: none; }

/* No-JS fallback: Joomla's own markup, made readable rather than restyled.
   NOT #system-message-container itself. That wrapper is always in the document
   and is empty on almost every page load, so giving it a background, padding
   and a shadow painted a permanent 560px white box across the top of every
   page - visible in the middle of the brand bar (0.62.3). Style only the alert
   Joomla renders INSIDE the wrapper, which exists only when there is something
   to say. */
.gtsbl-toasts:not(.is-live) joomla-alert,
.gtsbl-toasts:not(.is-live) .alert {
    pointer-events: auto;
    display: block;
    /* Joomla's own CSS puts min-width:250px on joomla-alert. Harmless at 390px
       and a fight waiting to happen on anything narrower, so it is cancelled
       here - the host already bounds the width. */
    min-width: 0;
    overflow-wrap: anywhere;
    background: #fff;
    color: #1a1a1a;
    border-radius: 10px;
    padding: 12px 14px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .18);
}

.gtsbl-toast {
    pointer-events: auto;
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px 14px;
    border-radius: 10px;
    background: #fff;
    color: #1a1a1a;
    border-left: 4px solid var(--gtsbl-toast-accent, #6b7280);
    box-shadow: 0 10px 30px rgba(0, 0, 0, .18), 0 1px 2px rgba(0, 0, 0, .06);
    font-size: 14px;
    line-height: 1.45;
    animation: gtsbl-toast-in .22s ease-out both;
}

.gtsbl-toast.is-going {
    opacity: 0;
    transform: translateY(-8px);
    transition: opacity .24s ease, transform .24s ease;
}

@keyframes gtsbl-toast-in {
    from { opacity: 0; transform: translateY(-10px); }
    to   { opacity: 1; transform: translateY(0); }
}

.gtsbl-toast.is-error   { --gtsbl-toast-accent: #c0392b; }
.gtsbl-toast.is-warning { --gtsbl-toast-accent: #d68910; }
.gtsbl-toast.is-notice  { --gtsbl-toast-accent: #2874a6; }
.gtsbl-toast.is-message { --gtsbl-toast-accent: var(--accent, #00ac8f); }

.gtsbl-toast-body { flex: 1; min-width: 0; }

.gtsbl-toast-label {
    display: block;
    font-weight: 700;
    font-size: 11px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--gtsbl-toast-accent, #6b7280);
    margin-bottom: 2px;
}

.gtsbl-toast-text { display: block; overflow-wrap: anywhere; }

.gtsbl-toast-x {
    flex: 0 0 auto;
    appearance: none;
    border: 0;
    background: transparent;
    color: #6b7280;
    font-size: 20px;
    line-height: 1;
    padding: 0 2px;
    cursor: pointer;
    border-radius: 4px;
}

.gtsbl-toast-x:hover { color: #1a1a1a; }
.gtsbl-toast-x:focus-visible { outline: 2px solid var(--gtsbl-toast-accent, #6b7280); outline-offset: 2px; }

/* Time remaining. Pauses with the timer while the pointer is on the toast. */
.gtsbl-toast-bar {
    position: absolute;
    left: 0;
    bottom: 0;
    height: 3px;
    width: 100%;
    background: var(--gtsbl-toast-accent, #6b7280);
    opacity: .45;
    transform-origin: left center;
    animation-name: gtsbl-toast-bar;
    animation-timing-function: linear;
    animation-fill-mode: forwards;
}

.gtsbl-toast.is-held .gtsbl-toast-bar { animation-play-state: paused; }

@keyframes gtsbl-toast-bar {
    from { transform: scaleX(1); }
    to   { transform: scaleX(0); }
}

@media (prefers-reduced-motion: reduce) {
    .gtsbl-toast { animation: none; }
    .gtsbl-toast-bar { animation: none; opacity: .25; }
    .gtsbl-toast.is-going { transition: none; }
}

@media (max-width: 640px) {
    .gtsbl-toasts { top: 8px; width: calc(100vw - 16px); }
    .gtsbl-toast { font-size: 13.5px; }
}


/* ---- phone header + hero (0.78.0) -------------------------------------
   Below 600px the nav row (logo + zone tagline + account controls) was one
   flex line with a 26px gap and a 230px logo, which is wider than a 390px
   phone: the Sign in button ran off the right edge and the PAGE scrolled
   sideways. Troy: "logo gets center, tag line under, then the buttons."
   Three centred rows, so nothing is cut off and nothing is hidden.
   ---------------------------------------------------------------------- */
@media(max-width:600px){
  .gtsbl-nav .nav-in{height:auto;flex-direction:column;align-items:center;gap:9px;padding-top:12px;padding-bottom:12px}
  .gtsbl-nav .brand{flex-direction:column;align-items:center;gap:6px;min-width:0;max-width:100%;text-align:center}
  .gtsbl-nav .nm-logo{height:30px;max-width:min(200px,62vw)}
  body.is-zone-home .gtsbl-nav .nm-logo,body.is-account .gtsbl-nav .nm-logo{height:36px;max-width:min(200px,62vw)}
  .gtsbl-nav .nm-wide{font-size:21px}
  .gtsbl-nav .nm-zone{border-left:0;padding-left:0;font-size:11.5px;line-height:1.35;text-align:center}
  .gtsbl-nav .nav-right{margin-left:0;justify-content:center;flex-wrap:wrap;gap:10px}

  /* Hero copy a notch smaller so the eyebrow, word and button all breathe. */
  .gtsbl-bhome .bh-eyebrow{font-size:11px;letter-spacing:.18em;margin-bottom:9px}
  .gtsbl-bhome .bh-rule{width:36px;margin-bottom:12px}
  .gtsbl-bhome .bh-word{font-size:clamp(30px,9vw,42px)}
  .gtsbl-bhome .bh-play{margin-top:18px;padding:10px 16px 10px 11px;font-size:13.5px}
  .gtsbl-bhome .bh-play svg{width:22px;height:22px;flex:0 0 22px}
  .gtsbl-bhome .bh-plabel{max-width:17ch}

  /* Account dropdown: anchored right:0 to the avatar BUTTON, so a 290px panel
     hung off the left edge of the screen once the controls were centred.
     Anchor it to the nav row instead - full width inside the shell gutters,
     which cannot overflow either edge at any phone width. */
  .gtsbl-nav .nav-in{position:relative}
  .gtsbl-nav .gtsbl-usr{position:static}
  .gtsbl-usr-menu{left:0;right:0;width:auto;top:calc(100% + 8px)}
}


/* ---- square corner style (0.79.0) --------------------------------------
   Troy: "rounded vs not rounded corners, can that be an option for styling"
   / "all the boxes and video player, the buttons can stay rounded"
   / "all the templates except the Admin dash".

   Site-wide template setting -> body.is-square. Only the BOX tokens are
   zeroed, so cards, heroes, banners, thumbnails, panels and the video stage
   go square while buttons, pills, chips, badges and avatars keep their shape
   - they carry their own literal radii and never touched these tokens.

   The admin console cannot be reached from here twice over: console.css uses
   var(--r) exactly ZERO times (it carries its own radii), and index.php does
   not emit is-square on a console page at all.
   ---------------------------------------------------------------------- */
body.gtsbl.is-square{--r:0px;--rs:0px;--rb:0px}
/* up-card is calc(var(--r) + 4px), which would still leave 4px at --r:0. */
body.gtsbl.is-square .gtsbl-upgrade .up-card{border-radius:0}


/* ---- B: collapse to the video after the fade (0.79.3) -------------------
   Troy: "the hero then the play keeps the hero size when it switches to play
   so it may have lots of black space."

   Measured on the live page before changing anything: the hero box is
   1228x1098 on a 1440 desktop and 588x706 at 620px, because is-natural sizes
   it from the brand PHOTO. A 16:9 video letterboxed into those loses 407px
   (37%) and 375px (53%) to black respectively - worse the narrower the screen,
   because the box turns portrait while the video stays landscape.

   The cause was deliberate: `.is-b.is-playing .bh-stage` sets
   `aspect-ratio:auto` and `inset:0`, cancelling the 16:9 every other mode
   gets, because the crossfade needs the player behind the hero at the same
   size. That is right DURING the fade and wrong once it is over.

   So B now settles. `is-settled` lands after the .55s fade: the hero leaves
   the flow, the stage gets its 16:9 back, and the container's height is
   animated down to meet it. Mode D has always done the equivalent
   (`.is-d.is-playing{min-height:0}` + hero `display:none`) - B just never had
   the second half.
   ---------------------------------------------------------------------- */
.gtsbl-bhome.is-b.is-settled{min-height:0;max-height:none;transition:height .38s ease}
.gtsbl-bhome.is-b.is-settled .bh-hero{display:none}
.gtsbl-bhome.is-b.is-settled .bh-stage{position:relative;inset:auto;aspect-ratio:16/9;height:auto}
@media(prefers-reduced-motion:reduce){.gtsbl-bhome.is-b.is-settled{transition:none}}


/* ---- phone heroes: the box grows to fit its text (0.79.7) ---------------
   Troy: "hero text and sizing issue" - the play button was sliced in half on
   his phone.

   Measured, not guessed. Goldwell's mobile hero photo is 1080x500 (2.16:1). On
   a 390px phone the content column is 358px, so the photo box is 166px tall -
   but the text block (eyebrow, rule, word, sub, play button) needs 189px. 23px
   overflowed and `overflow:hidden` cut it off. Adding the sub line is what
   tipped it over; before that it just squeaked in.

   Why it happened: in natural mode the container is min-height:0 and .bh-in is
   position:absolute, so the TEXT CONTRIBUTES NOTHING to the height. The box is
   exactly as tall as the photo, and anything taller than that is clipped. The
   category hero has the same shape - .hero-in anchored bottom:0 - which is why
   its eyebrow was cut off at the TOP.

   0.79.7 fixed it by putting the text back in normal flow and turning the photo
   into an absolutely-positioned COVER layer behind it. That did stop the
   clipping, and it cost the photo: `cover` fills by cropping, and because the
   box was then sized by the TEXT, the image had no say in the height at all.
   Troy, 0.79.22: "I just changed it to another image and it's staying the same
   height - the wide image ratio on mobile is not displaying correct." Exactly
   right, and it was this rule. Measured on the KAO zone home at 386px: the box
   was 110px tall while the mobile photo (1080x500, so 164px at that width)
   wanted 164 - a third of the picture's height thrown away - and swapping the
   short/square/tall mobile crop changed nothing, because the photo was never
   what set the height.

   Both can be true at once, and CSS grid is how: put the photo and the text in
   the SAME grid cell. The box is then as tall as whichever needs more, so
     - the photo keeps its own ratio and is never cropped or stretched,
     - the height follows the photo, so picking a different crop visibly works,
     - the text still overlays the image the way it does on a desktop,
     - and the text can never be clipped, because it is a real grid item and
       contributes its own height.
   Where the text is the taller of the two, the slack shows as plain background
   under the photo - Troy's stated preference: blank space is fine, cropping is
   not.

   The .is-a duplicates are not redundant. Mode A's own rules are one class more
   specific (.gtsbl-bhome.is-a.is-natural), so a plain .is-natural selector here
   would silently lose to them and mode A would keep clipping its text on a
   phone.
   ---------------------------------------------------------------------- */
@media(max-width:600px){
  /* brand-home hero, video and photo variants */
  .gtsbl-bhome.is-natural .bh-hero,
  .gtsbl-bhome.is-a.is-natural .bh-hero{display:grid;grid-template-columns:minmax(0,1fr);height:auto}
  .gtsbl-bhome.is-natural .bh-img,
  .gtsbl-bhome.is-a.is-natural .bh-img{position:relative;inset:auto;grid-area:1/1;align-self:start;width:100%;height:auto}
  .gtsbl-bhome.is-natural .bh-img img,
  .gtsbl-bhome.is-a.is-natural .bh-img img{width:100%;height:auto;min-height:0;object-fit:initial}
  .gtsbl-bhome.is-natural .bh-in,
  .gtsbl-bhome.is-a.is-natural .bh-in{position:relative;inset:auto;grid-area:1/1;align-self:end;padding-bottom:24px}
  .gtsbl-bhome.is-toptext.is-natural .bh-in,
  .gtsbl-bhome.is-a.is-toptext.is-natural .bh-in{align-self:start}

  /* page hero - the zone (KAO) home, and any brand home set to "No video hero" */
  .gtsbl-phero.is-natural{display:grid;grid-template-columns:minmax(0,1fr)}
  .gtsbl-phero.is-natural .gtsbl-phero-img{position:relative;inset:auto;grid-area:1/1;align-self:start;width:100%;height:auto}
  .gtsbl-phero.is-natural .gtsbl-phero-img img{width:100%;height:auto;min-height:0;object-fit:initial}
  .gtsbl-phero.is-natural .gtsbl-phero-in{position:relative;inset:auto;grid-area:1/1;align-self:end}
  .gtsbl-phero.is-natural.is-toptext .gtsbl-phero-in{align-self:start}

  /* category / featured hero - .hero-bg is already absolute, so only the text moves */
  .gtsbl-hero .hero-in{position:relative;left:auto;bottom:auto}
}


/* ---- tighten the hero text stack on phones (0.79.8) ---------------------
   Troy: "the padding between the text lines and the button is too much."

   Measured at a 358px column before changing anything: eyebrow->rule 9,
   rule->word 12, word->sub 18, sub->button 18 - and, worse, 38px of padding
   ABOVE the eyebrow against 0 below the button. Top-heavy, because
   `is-toptext` sets padding-bottom:0 - which was harmless while the text was
   absolutely positioned over a photo and became visible the moment 0.79.7 put
   it back in flow.

   TIGHTENED AGAIN in 0.79.24, for a different reason: not taste, but fit.
   Since 0.79.22 the hero box is as tall as the photo OR the text, whichever
   needs more - so when the text is the taller one the difference shows as a
   band of section background under the photo. Troy saw a black band on all
   three brands and said: "make it fit, but the button can get a little
   smaller and the spacing can tighten up between the button and the sub, and
   also the sub and the hero main text."

   Measured on kao-d1 at 389px, text 202 against a 165px photo - 37px to find:
     padding-top 24 + padding-bottom 24   the two edges, 48px of pure whitespace
     eyebrow 14, gap 7, rule 2, gap 10
     word 33
     gap 10 -> sub 23                     <- Troy's "sub and the hero main text"
     gap 12 -> button 42                  <- Troy's "button and the sub", and the button

   His three cuts are worth about 17px on their own, so the edge padding gives
   up the rest. Padding is whitespace rather than type, so it is the cheapest
   place to find the difference - the hero word keeps its size.
   ---------------------------------------------------------------------- */
@media(max-width:600px){
  .gtsbl-bhome .bh-eyebrow{margin-bottom:7px}
  .gtsbl-bhome .bh-rule{margin-bottom:10px}
  .gtsbl-bhome .bh-sub{margin-top:4px}
  .gtsbl-bhome .bh-play{margin-top:6px}
  /* "the button can get a little smaller" - vertical padding and label only. */
  .gtsbl-bhome .bh-play{padding-top:7px;padding-bottom:7px;font-size:13px}
  /* Measured after the cut: the button is 36px, under the 44px touch minimum -
     so the TAP TARGET is restored separately from the look. A transparent,
     absolutely-positioned pseudo-element is 44px tall and contributes NO layout
     height, so the thumb gets its target back and the band stays closed. Doing
     it with min-height would simply hand back the 6px we just found. */
  .gtsbl-bhome .bh-play{position:relative}
  .gtsbl-bhome .bh-play::after{content:"";position:absolute;left:0;right:0;top:50%;height:44px;transform:translateY(-50%)}
  .gtsbl-bhome.is-toptext .bh-in{padding-top:12px;padding-bottom:12px}
  .gtsbl-bhome .bh-in{padding-bottom:12px}

  /* the category / featured hero, same stack, same complaint */
  .gtsbl-hero .eyebrow{margin-bottom:9px}
  .gtsbl-main .gtsbl-hero h1{margin-bottom:10px}
  .gtsbl-hero .hero-sub{margin:0 0 12px}
  .gtsbl-hero .play{padding:11px 20px}
}


/* ---- Categories hero height, per brand (0.79.10) ------------------------
   Troy asked whether this hero should "look like the video heights", then
   chose to make it a page-builder setting rather than one decision for
   everyone.

   Why it matters, measured on the live page: the hero was 1228x240 - a 5.12:1
   strip - with a 16:9 thumbnail behind it on `cover`. To fill 1228px wide the
   thumb scales to 691px tall, so only 240px of it was ever visible and
   **65% of the video's frame was hidden**. That is why it read as a banner and
   why compositions landed badly in it.

   banner - today's 240px strip. Still the DEFAULT, so no brand changes shape
            until someone picks otherwise.
   video  - 16:9, capped so it cannot swallow the page. 1228x691 uncapped is
            exactly what the brand-home player collapses to, which is the point
            of the option; the cap trades a little crop for a reachable list.
   tall   - 16:9, uncapped. Zero crop, the thumbnail exactly as shot.

   The cap is lifted below 600px: there the text sits in normal flow (0.79.7)
   and a max-height would start clipping it again - the bug that fix existed to
   kill.
   ---------------------------------------------------------------------- */
/* width:100% is load-bearing. With `aspect-ratio` and an auto width, a
   max-height makes the browser shrink the WIDTH to keep the ratio - measured
   807px inside a 1228px column, a narrow box floating mid-page. A definite
   width means the ratio can only drive the height. */
.gtsbl-hero.is-h-video{width:100%;min-height:0;aspect-ratio:16/9;max-height:min(60vh,520px)}
.gtsbl-hero.is-h-tall{width:100%;min-height:0;aspect-ratio:16/9}
@media(max-width:600px){.gtsbl-hero.is-h-video,.gtsbl-hero.is-h-tall{max-height:none}}

/* Mode A sticks the hero to the top of the viewport - but the NAV is sticky at
   top:0 too, so the hero was parking underneath it and the nav ate the top of
   the hero. Harmless with bottom-anchored text, and it sliced the brand word in
   half with the text at the top (0.79.18). --gtsbl-navh is measured in JS
   because the nav is 118px on a desktop and taller on a phone, where the header
   stacks into three rows; the 0px fallback is simply today's behaviour if the
   script has not run yet. */

/* Mode A with a photo too short to fill the pinned hero (0.79.21).
   0.79.19 used a JS class - right about WHAT, wrong about WHEN: it landed
   after first paint, so the page jumped. 0.79.20 fixed the flash with pure
   CSS but paid for it with min-height:100% + object-fit:cover, which CROPS a
   short photo to fill the screen. On a phone with a 16:9 hero that is most of
   the picture gone. Troy's rule: never stretch, never crop, never repeat -
   empty space is the acceptable cost, not a cut-off image.

   So the hero stops being a fixed 100vh window and takes its height FROM the
   photo, capped at the screen:
     .bh-hero  height:auto + max-height - the cap is what still pins a tall
               photo to the viewport, so mode A is unchanged where it matters.
     .bh-img   back IN FLOW (position:relative), which is the only way the
               hero can size from it. The pan still transforms this element,
               and a transform works the same in flow as out of it.
     img       fully natural - no min-height, no object-fit.

   SHORT photo  -> hero == photo. Whole image, no crop, no empty band either.
   TALL photo   -> hero clamps at the screen, the photo overflows, `over` is
                   positive and the pan runs exactly as before.
   Both cases are the FIRST layout painted - still no JS in the decision. */
.gtsbl-bhome.is-a.is-natural .bh-hero{height:auto;max-height:calc(100vh - var(--gtsbl-navh,0px))}
.gtsbl-bhome.is-a.is-natural .bh-img{position:relative;inset:auto;height:auto}
.gtsbl-bhome.is-a.is-natural .bh-img img{width:100%;height:auto;min-height:0;object-fit:initial}
