/* ==========================================================================
   site-ux.css : navigation comfort layer
   - keeps the header of the geo-page template on screen while you scroll
   - turns its link row into a proper menu on phones
   - a quiet back-to-top control for long pages
   Everything is additive. Removing this file returns the old behaviour.
   ========================================================================== */

/* ----------------------------------------------------------- fixed header
   The geo-page template sets overflow-x:hidden on html and body, which turns
   them into scroll containers and quietly kills position:sticky. So this
   header is fixed instead, full width, with its inner padding matched to the
   .wrap column so the logo still lines up with the text below it.
   .has-geo-head is set by site-ux.js, so pages without this header are
   untouched. */
.has-geo-head header.site-head {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  width: auto;
  z-index: 60;
  padding-inline: max(20px, calc((100vw - 1180px) / 2));
  background: rgba(7, 7, 7, .93);
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
  border-bottom: 1px solid transparent;
  transition: border-color .25s ease, background .25s ease, padding .2s ease;
}
.has-geo-head header.site-head.is-stuck {
  background: rgba(7, 7, 7, .97);
  border-bottom-color: rgba(214, 174, 103, .22);
}
.has-geo-head body { padding-top: var(--ux-head-h, 78px); }
/* the page's own first section already has padding, so nothing else moves */

/* ------------------------------------------------- phone menu, geo pages */
.ux-menu-btn {
  display: none;
  order: 2;
  align-items: center;
  gap: 8px;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  color: var(--text, #f8f4ee);
  background: rgba(214, 174, 103, .10);
  border: 1px solid rgba(214, 174, 103, .38);
  border-radius: 999px;
  min-height: 44px;
  padding: 0 16px;
  cursor: pointer;
  touch-action: manipulation;
}
.ux-menu-btn:focus-visible { outline: 2px solid #f0d7a1; outline-offset: 2px; }
.ux-menu-btn i { font-style: normal; display: grid; gap: 3px; }
.ux-menu-btn i span { display: block; width: 16px; height: 2px; background: currentColor; border-radius: 2px; }

@media (max-width: 900px) {
  .has-geo-head header.site-head { flex-wrap: wrap; row-gap: 10px; padding-top: 12px; padding-bottom: 12px; }
  .has-geo-head header.site-head img { width: 104px; }
  .ux-menu-btn { display: inline-flex; }
  .has-geo-head header.site-head nav {
    display: none;
    order: 3;
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding: 6px 0 4px;
    max-height: calc(100dvh - var(--ux-head-h, 96px) - 12px);
    overflow-y: auto;
    overscroll-behavior: contain;
    border-top: 1px solid rgba(255, 255, 255, .10);
  }
  .has-geo-head header.site-head nav.is-open { display: flex; }
  .has-geo-head header.site-head nav > a,
  .has-geo-head header.site-head nav > .cta {
    min-height: 46px;
    display: flex;
    align-items: center;
    padding: 0 6px;
    border-radius: 10px;
  }
  .has-geo-head header.site-head nav > a:hover { background: rgba(255, 255, 255, .05); }
  .has-geo-head header.site-head nav > .cta { justify-content: center; margin-top: 6px; }
  /* the language switch sits in the bar, never inside the menu panel */
  .has-geo-head header.site-head .lang-switch { order: 1; margin-left: auto; margin-right: 4px; display: inline-flex; align-items: center; gap: 10px; }
  .has-geo-head header.site-head .ux-menu-btn { order: 2; }
  .has-geo-head header.site-head .lang-switch a,
  .has-geo-head header.site-head .lang-switch strong { min-height: 44px; display: inline-flex; align-items: center; padding: 0 4px; }
}

.ux-geo-menu-open, .ux-geo-menu-open body { overflow: hidden; }

/* ------------------------------------------------------------ back to top
   Bottom-LEFT is taken by the radar badge on the landing pages and
   bottom-right by the WhatsApp button, so this sits above the WhatsApp
   button and only appears once you are well down the page. */
.ux-top {
  position: fixed;
  right: 18px;
  bottom: 88px;
  z-index: 54;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  border: 1px solid rgba(214, 174, 103, .45);
  background: rgba(10, 10, 10, .82);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: #f0d7a1;
  cursor: pointer;
  opacity: 0;
  transform: translateY(10px);
  pointer-events: none;
  transition: opacity .2s ease, transform .2s ease;
  touch-action: manipulation;
}
.ux-top.is-on { opacity: 1; transform: none; pointer-events: auto; }
.ux-top:hover { background: rgba(20, 20, 20, .92); }
.ux-top:focus-visible { outline: 2px solid #f0d7a1; outline-offset: 3px; }
.ux-top svg { width: 18px; height: 18px; }

@media (max-width: 600px) { .ux-top { bottom: 82px; right: 14px; } }
@media (prefers-reduced-motion: reduce) {
  .ux-top, .has-geo-head header.site-head { transition: none; }
  html { scroll-behavior: auto; }
}
@media (forced-colors: active) {
  .ux-top, .ux-menu-btn { border: 2px solid ButtonText; }
}

/* ==========================================================================
   Line breaking
   Where a line ends is copywriting, not decoration: a headline that strands
   one word, or a Chinese line that ends on 的 or 与, reads as a stutter. The
   hand-placed <br> tags that used to force this were correct at exactly one
   screen width and wrong at every other, so the rules live here instead and
   hold at any width, in either language.
   ========================================================================== */

/* Balance spreads a heading evenly across its lines instead of filling the
   first and leaving a single word on the last. Browsers without it simply
   wrap as they do today, so there is nothing to fall back from. */
h1, h2, h3,
.hero-title, .card h3, .lead, blockquote, figcaption,
.faq-q, .prompt-title, .habit h3, .tool-card h3 {
  text-wrap: balance;
}

/* Pretty applies the same idea to running text: it prevents the last line of
   a paragraph being a single short word. */
p, li, dd, .muted, .note, summary {
  text-wrap: pretty;
}

/* Chinese wraps between any two characters, which is correct, but a Latin word
   or a number sitting inside Chinese must stay whole: 企业 AI 培训 may break
   around "AI", never through it. line-break:strict also keeps a line from
   opening with closing punctuation such as 、。」）. */
:lang(zh), [lang^="zh"], html[lang^="zh"] body {
  line-break: strict;
  word-break: normal;
  overflow-wrap: break-word;
}

/* Short, decisive labels should not break at all: a button that reads
   "Discuss" on one line and "Your Training" on the next looks like an error
   rather than a choice. They are short enough to shrink instead. */
.lang-btn, .ux-menu-btn, .pill, .tag, .badge,
.site-header nav a, .site-head nav a, .site-nav a, .site-footer nav a {
  white-space: nowrap;          /* supported everywhere, unlike text-wrap */
}
.cta, .btn {
  text-wrap: balance;           /* two even lines beat one long and one short */
}

/* A URL or a long identifier should wrap rather than push the page sideways. */
.break-anywhere, code, kbd, .url, .source-url {
  overflow-wrap: anywhere;
}

/* A hard break that only takes effect when both halves actually fit on a line
   of their own. "Stop experimenting in fragments. / Build your own AI creative
   system." reads as two beats on a laptop; on a tablet each half wrapped again
   and the heading landed in four lines with a stub at the end. Below the
   threshold the break is ignored and the balanced wrap takes over. */
br.br-opt { display: none; }
@media (min-width: 900px) {
  br.br-opt { display: inline; }
}

/* ==========================================================================
   RESPONSIVE SPACING PASS
   Layout only. No colour, type, copy or component changes.

   Audited by rendering all 63 pages at 320 / 390 / 430 / 768 / 1024 / 1280 /
   1440 and measuring the distance from the bottom of the fixed header to the
   first line of content. That distance ranged from -42px (content sitting
   UNDER the bar) to 251px across the site. It is one value now.

   This file is the only stylesheet loaded by every page, and it loads last
   on every template except the glossary, so the corrections live here rather
   than being scattered across eight sheets.
   ========================================================================== */

:root {
  /* The real height of the fixed bar, per breakpoint. style.css already has
     --header-h, but it is also the value .hero pads itself by, so it cannot
     absorb the scrolled state. This one tracks what is actually on screen. */
  --ux-hdr: 80px;

  /* The single clearance value: the air between the bottom of the bar and the
     first thing you read. 32px on a phone, 60px on a desktop — enough that a
     translucent bar never appears to be resting on the headline. */
  --ux-top: clamp(32px, 6.5vw, 60px);
}

@media (max-width: 1350px) { :root { --ux-hdr: 70px; } }

/* --------------------------------------------------------- 1. the bar itself
   style.css sets the header to 80px and shrinks it to 74px on scroll, which
   is correct on a desktop. But below 1350px the base height is 70px, so the
   same rule made the bar GROW by 4px the moment you started scrolling — on
   every phone, on every page. The hero's own padding-top is var(--header-h),
   i.e. 70px, so those 4px also cropped the top of the first line. Below the
   nav breakpoint the bar simply keeps its height. */
@media (max-width: 1350px) {
  .site-header.scrolled { height: var(--ux-hdr); }
}

/* --------------------------------------------------- 2. home page hero space
   The worst case on the site, and the most visited page. style.css gives the
   hero `padding-top: var(--header-h)` to clear the fixed bar, then the 1140px
   breakpoint adds `.hero-grid { padding-top: 16px }`. Those 16px were the
   entire gap between the header's bottom border and the eyebrow, from 320px
   all the way up to 1140px — phone, large phone and tablet alike. Above that
   width the grid centres itself in the viewport and the gap jumps to ~85px,
   so the page read as two different designs either side of the breakpoint. */
@media (max-width: 1140px) {
  .hero .hero-grid { padding-top: var(--ux-top); }
}

/* ------------------------------------------------- 3. geo-template top space
   These ~40 pages (About, HRD Corp, Case Studies, the training pages) offset
   their content with body padding equal to the measured header height. The
   measurement was being taken before the Menu button was inserted, so the
   stored value was always the height of a bar that no longer existed. The
   real fix is in site-ux.js; this is the floor it falls back to. */
.has-geo-head body { padding-top: var(--ux-head-h, 96px); }

/* ----------------------------------------------- 4. geo header on small phones
   Below about 430px the logo (112px) + language switch + Menu button no longer
   fit the available 280px, so the header wrapped to three rows and stood 144px
   tall — taller than the artwork it was covering. Everything on that row gives
   up a few pixels so it stays a row. */
@media (max-width: 430px) {
  .has-geo-head header.site-head { gap: 8px; column-gap: 8px; }
  .has-geo-head header.site-head img { width: 92px; }
  .has-geo-head header.site-head .ux-menu-btn { padding: 0 12px; font-size: 13px; gap: 6px; }
  .has-geo-head header.site-head .lang-switch { gap: 4px; font-size: .72rem; margin-right: 0; }
  .has-geo-head header.site-head .lang-switch a,
  .has-geo-head header.site-head .lang-switch strong { padding: 0 2px; }
}

/* Below 370px even that is not enough: the logo, the switch and the button
   need 288px of a 280px row. The button keeps its icon and drops its word —
   aria-label carries the name, so nothing is lost to a screen reader. */
@media (max-width: 370px) {
  .has-geo-head header.site-head { gap: 6px; column-gap: 6px; }
  .has-geo-head header.site-head img { width: 84px; }
  .has-geo-head header.site-head .ux-menu-btn { padding: 0; width: 46px; justify-content: center; }
  .has-geo-head header.site-head .ux-menu-btn .ux-menu-label { display: none; }
}

/* The label is a <b> only so it can be hidden above; it must not look bold. */
.ux-menu-btn .ux-menu-label { font-weight: 700; }

/* EN and 中文 were sitting on different baselines inside the switch. The
   current language is a <strong> and the other is an <a>, and they were
   resolving to different display values — inline-flex for one, block for the
   other — so one label centred itself in the 44px tap target and the other
   sat at the top of it. geo-page.css pins the <a> with `display:inline
   !important`, so this has to be both more specific and important to land.
   Both children now share one box and one centre line. */
.has-geo-head header.site-head .lang-switch { align-items: center; line-height: 1; }
.has-geo-head header.site-head .lang-switch > * {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

/* Shared header language controls, including pages without inline styles. */
.site-header .lang-toggle {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  overflow: hidden;
  border: 1px solid rgba(214,174,103,.5);
  border-radius: 6px;
}
.site-header .lang-toggle .lang-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 38px;
  min-height: 44px;
  padding: 7px 11px;
  border: 0;
  font-size: .76rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: .05em;
  color: rgba(248,244,238,.72);
  background: transparent;
}
.site-header .lang-toggle .lang-btn.active {
  color: #120e06;
  background: linear-gradient(135deg,#f0d7a1,#d6ae67);
}
.site-header .lang-toggle .lang-sep {
  width: 1px;
  height: 20px;
  flex-shrink: 0;
  background: rgba(214,174,103,.38);
}

/* ------------------------------------------- 5. the lead illustration, capped
   Free AI Tools, the AI Radar and Style Lab open with a glass illustration in
   a .ga-plate, which is allowed 720px. At 1440×900 that renders 480px tall and
   pushed the headline it introduces to y=632 — below the fold on a laptop. The
   plate was also centred while every line of copy under it is left-aligned, so
   the page had two competing left edges.

   The illustration is an introduction, not the page. It keeps its full width on
   a phone (where the column is narrower than the cap anyway) and is held to a
   sensible size above that, aligned to the same edge as the text. */
.ga-lead .ga-plate { margin-bottom: clamp(18px, 2.4vw, 26px); }

.ga-lead .ga-plate,
.ga-lead .ga-plate.ga-plate--sm,
.ga-lead .ga-plate.ga-plate--center {
  max-width: min(420px, 100%);
  margin-inline: 0;
}

/* --------------------------------------------- 6. article and 404 top space
   toolkit.css opens these with `calc(var(--header-h) + 26px)`. The 26px was
   the whole clearance, and --header-h is the unscrolled height, so the
   breadcrumb sat under the bar as soon as the page moved. */
.tk-doc-top { padding-top: calc(var(--ux-hdr) + var(--ux-top)); }

/* ------------------------------------------------------ 7. anchor landings
   Jumping to #programs or #contact put the target under the fixed bar: the
   existing scroll-margin uses the unscrolled header height with nothing to
   spare. Give every in-page target the bar plus a readable margin. */
main [id],
section[id],
.section[id] { scroll-margin-top: calc(var(--ux-hdr) + 20px); }

.has-geo-head main [id],
.has-geo-head section[id] { scroll-margin-top: calc(var(--ux-head-h, 96px) + 20px); }

/* ---------------------------------------------------------- 8. glossary page
   The one template that loads its own sheet AFTER this file, so this rule is
   written a level more specific to land at all. glossary.css hard-codes
   `padding-top: 104px` for every width: 34px of clearance under a 70px phone
   bar, 24px under an 80px desktop one — backwards, since the desktop has the
   room. */
body.glossary-page .gl-main { padding-top: calc(var(--ux-hdr) + var(--ux-top)); }

/* ------------------------------------ 9. the nowrap rule, kept off content
   The rule above used to end in a bare `nav a`, written for the header link
   row. But `.tk-jump` — the card row under the Free AI Tools headline, and the
   one on the 404 page — is also a <nav>, so every card's description became a
   single unbreakable line and was clipped at the card's edge: "Pick a task,
   answer 2 or 3 questi". It never showed as a broken page because style.css
   locks overflow-x on html and body, which hid the spill instead of the cause.
   The selector is scoped to the navigation bars it was written for. */
.tk-jump a,
.tk-jump b,
.tk-jump span,
.tk-jump em { white-space: normal; }


/* UI icons have explicit intrinsic dimensions as well as CSS bounds.
   Keep these scoped to interface icons; SVG filter definitions and content
   artwork must retain their own geometry. */
body svg.ui-icon {
  display:inline-block;
  vertical-align:middle;
  width:18px;
  height:18px;
  max-width:24px;
  max-height:24px;
  flex:0 0 auto;
}
body svg.ui-icon.ui-icon--22 { width:22px; height:22px; }
body svg.ui-icon.ui-icon--24 { width:24px; height:24px; }

/* The Chinese visibility-checker template lacked its footer icon styles.
   Define the component once for every page instead of relying on inline CSS. */
.site-footer .footer-social {
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:12px;
  margin-top:16px;
}
.site-footer .footer-social a {
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:44px;
  height:44px;
  flex:0 0 44px;
  border:1px solid rgba(214,174,103,.45);
  border-radius:50%;
  color:#f0d7a1;
  background:rgba(214,174,103,.08);
  line-height:1;
}
.site-footer .footer-social a svg {
  display:block;
  width:18px;
  height:18px;
  max-width:18px;
  max-height:18px;
  flex:0 0 18px;
}
.site-footer .footer-social a:focus-visible { outline:2px solid #f0d7a1; outline-offset:3px; }
