/* 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:#1B1917; --teal:#1B1917; --teal-light:#D8D0C0; --teal-deep:#1B1917; --teal-pale:#EFE9DC;
  --page:#F6F2EA; --offwhite:#FBF8F1; --border:#D8D0C0; --muted:#57534A; --faint:#8F887B;
  --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:'IBM Plex Sans',Segoe UI,system-ui,sans-serif; line-height:1.5;
  font-variant-numeric:tabular-nums; -webkit-font-smoothing:antialiased; }

/* 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); 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. */


/* The action cards. */
.cardgrid { display:grid; grid-template-columns:1fr; gap:18px; }
.cardgrid--two { grid-template-columns:1fr 1fr; }
@media (max-width:700px) {
  .cardgrid--two { grid-template-columns:1fr; }
}

/* The document cards (hub.js docCard): the Index Report, its issue panel and
   the Tailored Client Report. Words left, the action right; on a phone the
   action goes under the words. It was an inline grid, which this media query
   could not reach, so the issue button kept its width beside a column of
   words a few wide. */
.doccard { padding:16px 22px; display:grid; grid-template-columns:minmax(0,1fr) auto;
  gap:6px 16px; align-items:baseline; }
.doccard__act { display:flex; flex-wrap:wrap; gap:8px; justify-content:flex-end; }
@media (max-width:700px) {
  .doccard { grid-template-columns:minmax(0,1fr); gap:12px; }
  .doccard__act { justify-content:flex-start; }
}

/* 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; }
@media (max-width:700px) {
  .toprow { flex-direction:column; align-items:flex-start; gap:10px; }
  .toprow-util { margin-left:0; }
}

/* ---- the tab pill -------------------------------------------------
   A ROW OF TABS THAT DOES NOT FIT LOSES ITS LAST TAB SILENTLY. Four
   segments at 22px of padding each need ~400px; a phone card had 294px;
   the card clips its overflow, so Manage - the administrator's whole
   reason for being here - was not narrow, or wrapped, or scrolled off. It
   was invisible, and nothing on screen said a fourth tab existed.

   So the pill stops being a row when it stops fitting. A 2-column grid
   rather than flex-wrap: wrapping puts whatever happens to fit on row one
   and the remainder alone on row two, which changes shape with the label
   text and the tab count. Two columns is the same block whoever is
   reading, and a lone last tab spans the pair rather than leaving a hole.

   Horizontal scroll was the other candidate and is the same bug with a
   gesture attached: the fourth tab is still off-screen at rest, and this
   is a page people visit once a quarter, having forgotten it exists. */
.tabpill { display:inline-flex; gap:2px; background:#fff;
  border:1.5px solid var(--border); border-radius:50px; padding:4px; }
/* Labels never wrap. "Course group" broken across two lines inside a pill
   is what made the row taller than its own border in the first place. */
/* text-align BELONGS TO THE SEGMENT, not to one of the two elements that can
   be one. A tab is a link until it is the page you are on, and then it is a
   span - and only the link was centred inline, so the tab you were ON drew its
   label hard left inside its own pill the moment the pill became a grid and
   stretched it. A button centres its own label and an inline-block span does
   not, which is exactly why this cannot be left to the element. */
.tabseg { cursor:pointer; font-size:14px; font-weight:700; padding:9px 22px;
  border-radius:50px; border:none; transition:all .2s; white-space:nowrap;
  text-align:center; }
/* ⚠ 700px, NOT 560, AND IT IS THE SAME NUMBER AS .toprow's ON PURPOSE. The
   grid used to start at 560 while the row stacked at 700, so between the two
   the pill was an inline-flex block sitting at content width under a
   left-aligned logo, with a hand's width of nothing beside it - the shape a
   phone in landscape and a small tablet in portrait both land on, and the one
   that reads as "the nav left-aligns on some screens" (Finlay, 4 September
   2026). One breakpoint governs the arrangement now: the moment the pill stops
   sharing a row, it spans the row.

   ONE LINE OF EQUAL COLUMNS HERE, NOT THE TWO-COLUMN GRID. Between 561 and 700
   there is room for all three tabs at full size, and a two-column grid there
   put Partner alone on a second row under Personal | Organisation - a 2+1
   block on a screen that had fitted them on one line before. Column flow with
   1fr auto-columns spans the row with however many tabs the reader has.

   ⚠ THE PILL IS AT MOST TWO SEGMENTS SINCE 19 SEPTEMBER 2026 (chrome.js's
   PARTNER_HUB moved Partner to the utility line), so the 2+1 block these rules
   were written against cannot happen today. They stay as they are rather than
   being trimmed to two: the count is the READER'S, not the design's - one
   segment for a reader with no organisation grant, two for everyone else - and
   rules that hold for however many tabs there are do not need revisiting the
   next time the count moves. The odd-count rule below is what draws the
   one-segment pill properly.

   These rules are in hub.css rather than injected from chrome.js, and inline
   centring is gone from navRow with them: editing hub.css for the nav was
   approved by Finlay on 10 September 2026, over the D118 reasoning that had
   kept this build out of the shared stylesheet. */
@media (max-width:700px) {
  .tabpill { display:grid; grid-auto-flow:column; grid-auto-columns:1fr;
    gap:4px; width:100%; }
}
/* THE TWO-COLUMN GRID IS HALF A PHONE'S QUESTION, so it starts at 560. Three
   tabs at full size no longer fit one line there, and two columns is the same
   block whoever is reading (see the note above .tabpill). */
@media (max-width:560px) {
  .tabpill { grid-auto-flow:row; grid-template-columns:1fr 1fr;
    border-radius:26px; }
  /* An odd tab count - one tab, or three - would otherwise sit in the left
     column with a gap beside it that looks like a tab failed to draw. */
  .tabseg:last-child:nth-child(odd) { grid-column:1 / -1; }
}
/* THE SMALLER TYPE STAYS AT 560, because it answers a different question. The
   grid above is about the arrangement; this is about a tab that has to be
   readable and hittable in half of a phone's width, and at 620px there is room
   for the full-size label. Splitting them is what lets the arrangement move
   without shrinking the tabs on a tablet.

   14px of padding, not 10. A button does not inherit the body's line-height -
   it computes `normal` - so 13px type in 10px of padding measured 36px tall,
   which is under the 44px a finger is designed against and SMALLER than the
   39px these had before this file touched them. Making a tab visible on a
   phone and harder to hit on a phone is half a fix. */
@media (max-width:560px) {
  .tabseg { padding:14px 12px; font-size:13px; }
}

/* ---- 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; }

/* 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; }

/* ---- 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.

   ⚠ THIS WAS TWO COMMENTS UNTIL 15 SEPTEMBER 2026, and the first closed
   early: the paragraph below sat outside any comment, became part of the
   selector, and the browser threw the whole #hub rule away. The footer
   never reached the bottom on any hub page. css-comments.test.js now
   fails on a stray closer.

   ⚠ 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 mounts elsewhere and keeps its own
   layout. */
#hub { display:flex; flex-direction:column; min-height:100vh; }
@supports (min-height:100dvh) { #hub { min-height:100dvh; } }

/* Headings in Archivo, the wordmark's face (docs/brand-identity.md section 3). */
h1, h2, h3 { font-family: 'Archivo', 'IBM Plex Sans', system-ui, sans-serif; letter-spacing: -0.02em; }

/* THE NEXT MOVES (WP11) and "Was this useful?" (WP11b), as brand.css draws
   them on the report, in this page's tokens. */
.moves { margin: 12px 0 0; padding-left: 20px; }
.move { margin: 0 0 14px; font-size: 15px; line-height: 1.5; }
.move__text { margin: 0; }
.move__beta { margin: 4px 0 0; font-size: 13px; color: var(--muted); font-style: italic; }
.move__useful { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 0 0; font-size: 14px; }
.move__useful-ask { color: var(--muted); }
.move__useful-taps { display: inline-flex; gap: 8px; }
.move__tap { min-height: 44px; min-width: 64px; padding: 6px 14px; font: inherit; font-weight: 600; color: var(--navy);
  background: #fff; border: 1px solid var(--border); border-radius: 0; cursor: pointer; }
.move__tap:hover { background: var(--teal-pale); }
.move__tap:focus-visible { outline: 2px solid var(--navy); outline-offset: 3px; }
.move__tap:disabled { opacity: 0.6; cursor: default; }
.move__useful-status { margin: 0; font-size: 13px; color: var(--muted); }

/* The report layout (orl-*, prl-*) is /assets/report-layout.css, shared
   with the result page (13 October 2026). */
