/* THE HUB'S ONE STYLESHEET, shared by every instrument's hub page.

   Extracted from /aiprofile/hub/index.html the day the second hub folder
   appeared: three copies of 180 lines of layout is how the folders drift
   apart, and the entire point of the shell is that they cannot. An
   instrument's hub page carries its own title and script tags and NOTHING
   in here - a rule an instrument needs for itself has not been designed
   yet, and should go through the shell when it is. */
:root {
  --navy:#14212E; --teal:#2DA584; --teal-light:#3DC496; --teal-deep:#1f7c60; --teal-pale:#edf8f4;
  --page:#eef2f5; --offwhite:#f8fafb; --border:#e2eaef; --muted:#5a7181; --faint:#aab5be;
  --weak:#e0a3a3; --amber-bg:#fbf3e8; --amber-bd:#efe0c8; --amber-tx:#a9741f;
}
* { box-sizing:border-box; }
body { margin:0; background:var(--page); color:var(--navy);
  font-family:Inter,Segoe UI,system-ui,sans-serif; line-height:1.5;
  font-variant-numeric:tabular-nums; -webkit-font-smoothing:antialiased; }
/* The radar's natural width, shared by the grid column and the SVG element.
   The SVG's own coordinates stay in its viewBox, so shrinking it here scales
   the drawing rather than cropping it - RADAR_W in hub.js is viewBox maths
   and is deliberately left alone. */
:root { --radar-w:480px; }

/* THE CARD'S SIDE GUTTER, in one place. Every band inside the card was
   written `padding:28px 34px` inline, thirty times over, and 68px of it is
   a fifth of a phone screen spent on white space either side of content
   that has none to spare. A custom property is the one form of inline
   style a breakpoint can still reach: `padding:28px var(--gut)` stays
   inline and changes anyway. */
:root { --gut:34px; }
@media (max-width:560px) { :root { --gut:18px; } }

.wrap { max-width:1120px; margin:0 auto; padding:40px 20px 64px; }
@media (max-width:560px) { .wrap { padding:24px 14px 48px; } }
.eyebrow { font-size:12px; font-weight:700; letter-spacing:0.14em; text-transform:uppercase; color:var(--teal-deep); margin:0; }
a { color:var(--teal-deep); }
button { font-family:inherit; }

/* ---- responsive ---------------------------------------------------
   The hub declares a mobile viewport and had NO media query anywhere.
   Every side-by-side layout was an inline grid built in hub.js, and an
   inline style cannot carry a breakpoint - so the columns held at any width
   and a phone got two half-width columns of a chart and a headline.

   These classes exist so the widths have somewhere to change. They are not
   new layouts; they are the same ones, moved out of the JS. */

/* Chart beside words - the You tab uses it. 0.92fr because the right-hand
   column is prose, and a square chart set against a 44px headline in an
   equal column looks like the smaller of the two. */
.hubsplit { display:grid; grid-template-columns:1fr 0.92fr; gap:44px; }
@media (max-width:820px) { .hubsplit { grid-template-columns:1fr; gap:28px; } }

/* Two equal columns: the training hub's workshops, its indices cards and its
   Benchmark Lab cards. Not .hubsplit, whose 0.92fr is for a words side
   beside a picture. Top-aligned by default; a row whose cards should match
   in height stretches them (training.js standSection, elsewhereSection). */
.orgsplit { display:grid; grid-template-columns:1fr 1fr; gap:40px; align-items:start; }
@media (max-width:820px) { .orgsplit { grid-template-columns:1fr; gap:28px; } }

/* The right-hand column's own stack: headline, tiles, rule, spread chart. */
.orgcol { display:flex; flex-direction:column; gap:20px; }

/* The three company figures. A wrapping flex row used to degrade on its own;
   equalising the widths took that away, so a breakpoint has to give it back.
   Straight to one column rather than two-and-a-spare, which is the
   arrangement that made these look wrong in the first place. */
.stattiles { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px; }
@media (max-width:560px) { .stattiles { grid-template-columns:1fr; } }

/* Radar beside its list of six areas. THE FIXED 416px COLUMN IS WHY THE
   WHOLE PAGE OVERFLOWED SIDEWAYS: 416 plus 68 of padding is 484px, wider
   than any phone, so the card could not fit the viewport and every heading
   and paragraph on the page ran off the right edge. A grid column given a
   pixel width does not shrink - min-content is that width. */
.radarsplit { display:grid; grid-template-columns:var(--radar-w) minmax(0,1fr); gap:48px; align-items:center; }
/* NOT justify-items:center when stacked. That stops grid items stretching, so
   the six-area list beside the radar would size to its own content - and its
   progress bars, which are width:100% of whatever holds them, would collapse
   to that. Centring the RADAR is the actual intent, so the radar centres
   itself and the list is left to fill the row. */
/* STACKS EARLIER THAN THE OTHER TWO SPLITS, at 900 rather than 820, because
   this is the one grid with a FIXED column and that column grew to 480px.
   What is left for the list is the viewport less 40 of page padding, 68 of
   gutter, the radar and the 48 gap - so at 820 the list had 249px when the
   radar was 416 and would have 185 now, which is not a column of labelled
   bars, it is a squeeze. 900 gives it 264 and keeps the two-column layout
   only where it still reads. Below that the radar stacks and centres at its
   own width, which was always the better of the two shapes when space is
   short. */
@media (max-width:900px) { .radarsplit { grid-template-columns:1fr; gap:20px; } }

/* The radar SVG had the same width in pixels on the element itself. */
.radar { width:var(--radar-w); max-width:100%; height:auto; display:block; margin:0 auto; }

/* Three next moves, and the action cards. */
.movegrid { display:grid; grid-template-columns:repeat(3,1fr); gap:16px; }
.cardgrid { display:grid; grid-template-columns:1fr; gap:18px; }
.cardgrid--two { grid-template-columns:1fr 1fr; }
@media (max-width:700px) {
  .movegrid, .cardgrid--two { grid-template-columns:1fr; }
}

/* The tab pill and the line explaining it. Held on one row, the sentence was
   squeezed into a four-word-wide column running off the edge. */
.toprow { display:flex; align-items:center; gap:16px; }
/* THE UTILITY LINE'S PUSH TO THE RIGHT, AND WHY IT IS A CLASS RATHER THAN AN
   INLINE MARGIN. On one row it belongs hard right, opposite the logo. Stacked,
   it is the third item in a left-aligned column and an auto margin puts it
   alone on the right, under a logo and a pill that both start at the left edge
   - three items, two alignments, and it reads as the nav having come apart
   (Finlay, 4 September 2026). Written inline it could not be undone at a
   breakpoint at all, which is how it survived. */
.toprow-util { margin-left:auto; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
/* ---- the Account menu: the phone header ----------------------------
   ONE ROW ON A PHONE (Finlay, 23 October 2026, design_handoff_hub_header):
   the logo, and an "Account" pill that opens a menu holding the address,
   Your details, theailab.co.uk and Sign out (chrome.js accountMenu). It
   replaced two rows, and before them three. At 701px and up the utility line
   is unchanged and the menu is not drawn.

   ⚠ YOUR DETAILS IS TWO PRESSES AWAY HERE, AND THAT IS FINLAY'S DECISION, not
   a slip against D122's "one click from every hub page" (amended 23 October
   2026 in docs/consent-model-design.md). On a wide screen it is still one.

   The signed-out bar (logoBar) has no menu and keeps its utility line, the
   website link alone: only a line drawn after the menu gives way to it. */
.ail-acct { display:none; }
@media (max-width:700px) {
  /* Wraps rather than overflows: at a large text size the pill goes under
     the logo instead of off the screen. */
  .toprow { position:relative; flex-wrap:wrap; }
  .ail-acct + .toprow-util { display:none; }
  .ail-acct { display:block; margin-left:auto; }
}
.ail-acct-btn { display:inline-flex; align-items:center; gap:8px; height:40px;
  padding:0 6px 0 14px; border-radius:50px; border:1.5px solid var(--border);
  background:#fff; color:var(--navy); font:inherit; font-size:14px; font-weight:600;
  cursor:pointer; transition:all .25s ease; }
.ail-acct-btn svg { transition:transform .25s ease; }
.ail-acct-btn[aria-expanded="true"] { border-color:var(--teal); background:var(--teal-pale); }
.ail-acct-btn[aria-expanded="true"] svg { transform:rotate(180deg); }
.ail-acct-menu { position:absolute; top:calc(100% + 8px); right:0; width:260px;
  max-width:100%; background:#fff; border:1.5px solid var(--border); border-radius:14px;
  box-shadow:0 6px 24px rgba(20,33,46,.12); padding:6px; z-index:20; }
.ail-acct-menu[hidden] { display:none; }
.ail-acct-who { padding:10px 12px 8px; border-bottom:1.5px solid var(--border); margin-bottom:4px; }
.ail-acct-who p { margin:0; }
/* --teal-deep, not the handoff's --teal: 11px text needs 4.5:1, and --teal
   on white is about 3.1:1 (the hub's .eyebrow made the same move). */
.ail-acct-who .ail-acct-eyebrow { font-size:11px; font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--teal-deep); margin-bottom:4px; }
.ail-acct-email { font-size:13.5px; color:var(--navy); word-break:break-all; }
.ail-acct-item { display:flex; align-items:center; min-height:44px; padding:0 12px;
  border-radius:8px; font-size:14.5px; font-weight:600; color:var(--navy);
  text-decoration:none; }
.ail-acct-item--quiet { color:var(--muted); }
a.ail-acct-item:hover, a.ail-acct-item:focus-visible { background:var(--teal-pale); color:var(--teal-deep); }
.ail-acct-item--here { color:var(--teal-deep); }
.ail-acct-confirm { display:flex; align-items:center; gap:8px; min-height:44px;
  padding:0 12px; font-size:14.5px; font-weight:600; color:var(--navy); }
@media (prefers-reduced-motion:reduce) {
  .ail-acct-btn, .ail-acct-btn svg { transition:none; }
}

/* ---- the tab pill: gone ------------------------------------------
   .tabpill and .tabseg, the account hub's Personal | Organisation | Partner
   pill and its phone grid, left in F4 PR 2 with the account hub (runbook F4).
   The training hub has no pill. */

/* ---- the header identity line -------------------------------------
   Logo, rule and name held one row at every width, so the name and the
   "Signed in as ..." line under it were squeezed into whatever was left -
   about 190px on a phone. An email address does not wrap gracefully into
   that: it broke after "Signed in", again mid-address, and how bad it
   looked depended on how long the address was.

   Below 560 the logo takes its own row and the identity block takes the
   card's full width, which is the one width guaranteed to be enough for
   the longest thing here. anywhere-break stays as the backstop for an
   address longer than a phone is wide - it wraps rather than pushing the
   card sideways. */
/* ⚠ .hubhead, -who, -rule and -id ARE GONE, WITH THE HEADER THEY DRESSED.
   That header was logo | rule | name, in one row inside the card, and the
   chrome replaced it with two bands: the logo and the session line in the
   portal nav, the name in the page banner. Nothing rendered them any more, and
   a rule nothing draws is a rule that stops being true without anyone
   noticing.

   Two properties for one job, and this one stays because the problem does:
   an address longer than a phone is wide must break inside its own box rather
   than push the document sideways. `anywhere` is the one that also lets the
   box's min-content shrink; `break-word` is the older spelling, for the iOS
   versions before 15.4 that do not know the newer one. */
.hubhead-sub { overflow-wrap:anywhere; word-break:break-word; }

/* ---- the body panel ------------------------------------------------
   Every top-level section in the hub opens with its own border-top, which
   was right when the card began with a header: the rule separated the
   header from the first section. The chrome moved the header into a band
   of its own, so that rule now lands directly under the panel's own
   border and draws a doubled hairline along the top edge.

   !important because the border is set inline, thirty times over, and one
   rule here is better than thirty edits to the file the three live hubs
   share. It reaches nothing else: .hubbody exists only where hub.js puts
   it, which is the one element holding the sections. */
.hubbody > *:first-child { border-top:0 !important; }

/* 44px is a desktop headline. "The Operator" alone is wider than a phone at
   that size, which is why it broke across two lines and still overflowed. */
.bighead { font-size:clamp(30px,7vw,44px); font-weight:800; letter-spacing:-0.02em; margin:0 0 6px; }

/* Nothing may push the page wider than the screen. A backstop, not a
   licence: anything that needs to be wider than the viewport should scroll
   inside its own box rather than take the document with it. */
html, body { overflow-x:hidden; }
/* As style.css: no iOS landscape text inflation. */
html { -webkit-text-size-adjust:100%; text-size-adjust:100%; }

/* ---- the footer ends the page, at any length ----------------------
   The chrome's ink band closes the document, and on a SHORT page it was
   closing it half way down the screen with grey below - which reads as
   content that failed to load rather than as the end. A course group
   below the floor is the honest case: a banner, one explanatory panel,
   and nothing else the reader is allowed to see.

   min-height on the mount rather than position:fixed, so the band still
   scrolls away on a long page and is never furniture stuck to the
   viewport. 100dvh rather than 100vh because a mobile browser's toolbar
   makes vh taller than the visible area, which would push the footer
   just off the bottom of the one screen size that can least afford it -
   with vh as the fallback for anything that does not know dvh.

   The mount is a flex column so the last band takes the slack: without
   that, min-height stretches the box and leaves the footer where it
   was, with the gap underneath it rather than above. */
   ⚠ THE FOOTER IS NOT ALWAYS #hub's LAST CHILD, which is why the push
   lives on the band itself rather than on a :last-child rule. The leaf
   hub appends nav, banner, body and footer straight onto the mount; the
   sign-in gate and the error state put all four INSIDE one container.
   A :last-child rule would have pushed that whole container down and
   floated the error page in the middle of the screen.

   So chrome.js's card() grows and the footer takes the slack wherever it
   sits. Scoped to #hub: company.html and survey.html mount elsewhere and
   keep their own layout. */
#hub { display:flex; flex-direction:column; min-height:100vh; }
@supports (min-height:100dvh) { #hub { min-height:100dvh; } }
