/* ══════════════════════════════════════════════════════════════════════════
   THE TOOLS HUB — app.<basedomain>/

   The rail's catalogue, opened out flat. It shares the rail's grammar on
   purpose: same 24px 1.3px-stroke group glyph, same 6px item radius, same
   accent-soft hover, same `--tp-*` ink indirection. A visitor sees both
   surfaces at once at desktop, so the two must read as one object.

   COLOUR: tokens only, no raw hex, no gradients. The three theme states —
   un-stamped, data-theme="light", data-theme="dark" — are handled entirely by
   style.css re-pointing these same token names, so this file carries no theme
   selector of its own except the one un-stamped override the rail also needs
   (see `--tp-ink` in tool-portal.css for why that one exists).

   SPACING: every length below is on the ramp {0,4,8,12,16,24,32,48,60,80,120}.
   RADII:   6 (cards + chips share the rail's item radius), 12 (the group
            surface, this system's --radius), 9999 (the Soon pill).
   MOTION:  --qf-dur / --qf-dur-fast, one easing. Nothing new is introduced.
   BORDERS: 2px, as the system requires. The card's resting border is 2px of
            --border and the hover state re-colours it rather than thickening
            it, so nothing reflows on hover.
   ══════════════════════════════════════════════════════════════════════════ */

.qf-hub {
  /* NO RAIL OFFSET HERE, DELIBERATELY. The rail is `position: fixed` at
     >=1024px and tool-portal.css already clears it by putting
     `padding-left: var(--tp-w)` on the BODY - every page on this host inherits
     that, and the hub is not special. An offset here as well indented the page
     twice: measured 500px of left margin on a 1440 viewport, a 940px content
     column where 1190 was free, and a card grid that fell to two columns
     because of it. */
  display: block;
  max-width: 1100px;
  margin: 0 auto;
  padding: 32px 16px 80px;
  text-align: left;
}

/* ── The intro. Eyebrow top-left, heading left. ────────────────────────────
   Stated rather than inherited: this host renders inside the same
   `public-pages-wefixtrades` skin the marketing site uses, and that skin's
   shared `.hero` centres its children. A hub whose H1 drifted to the middle
   the next time that sheet is touched would be a silent regression of a house
   rule, so the alignment is declared here where the rule applies. */
.qf-hub__intro {
  text-align: left;
  margin-bottom: 48px;
}

.qf-hub__eyebrow {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}

.qf-hub__title {
  margin: 0 0 12px;
  text-align: left;
  font-size: 36px;
  line-height: 1.15;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--ink);
  /* THE TITLE MUST NOT DROP ONE WORD ONTO A LINE OF ITS OWN. `balance` splits
     the two lines evenly instead of filling the first and orphaning "place".
     Unsupported engines simply fill as before — this is a refinement, not a
     dependency, and the copy is short enough to be acceptable either way. */
  text-wrap: balance;
}

.qf-hub__lede {
  margin: 0;
  max-width: 560px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--muted);
}

/* ── A group ──────────────────────────────────────────────────────────────
   No card, no box. The heading plus a hairline is enough separation for a page
   whose content is already six visually distinct grids, and boxing each group
   would nest a bordered surface inside a bordered surface for every card. */
.qf-hub__group { margin-top: 48px; }
.qf-hub__group:first-of-type { margin-top: 0; }

.qf-hub__grouphead {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-bottom: 12px;
  margin-bottom: 24px;
  border-bottom: 2px solid var(--surface-3);
}

/* The rail's icon box, to the pixel: 24x24, accent ink. */
.qf-hub__ico {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  color: var(--accent);
}
.qf-hub__ico svg { width: 24px; height: 24px; display: block; }

.qf-hub__h {
  margin: 0;
  text-align: left;
  font-size: 20px;
  line-height: 1.4;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* ── The grid ─────────────────────────────────────────────────────────────
   `auto-fill` with a 300px floor resolves to three columns inside the 1100px
   content box, two from ~700px, and one below ~640px — without a single
   width-keyed override. A trailing row that is not full is left alone: these
   are index entries in a long list, not a row of four buttons, and the
   no-orphan rule exists for the latter. Stretching two cards across three
   columns would make a two-tool group look like a section of the page rather
   than two tools. */
.qf-hub__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 16px;
}

.qf-hub__card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  position: relative;
  padding: 16px;
  padding-right: 48px;
  border: 2px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  text-decoration: none;
  transition:
    border-color var(--qf-dur-fast, 140ms) var(--qf-ease, cubic-bezier(.2, .7, .2, 1)),
    background-color var(--qf-dur-fast, 140ms) var(--qf-ease, cubic-bezier(.2, .7, .2, 1)),
    box-shadow var(--qf-dur-fast, 140ms) var(--qf-ease, cubic-bezier(.2, .7, .2, 1));
}

.qf-hub__card-t {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink);
}

.qf-hub__card-d {
  font-size: 13px;
  font-weight: 400;
  line-height: 1.5;
  color: var(--muted);
}

/* The arrow. Present at rest at low emphasis rather than appearing on hover:
   a control that materialises under the cursor tells a touch visitor nothing,
   and the reserved 48px of right padding above means it never overlaps the
   copy at any width. */
.qf-hub__go {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 16px;
  height: 16px;
  color: var(--muted-soft);
  transition:
    color var(--qf-dur-fast, 140ms) var(--qf-ease, cubic-bezier(.2, .7, .2, 1)),
    transform var(--qf-dur-fast, 140ms) var(--qf-ease, cubic-bezier(.2, .7, .2, 1));
}
.qf-hub__go svg { width: 16px; height: 16px; display: block; }

a.qf-hub__card:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: var(--shadow-sm);
}
a.qf-hub__card:hover .qf-hub__card-t { color: var(--accent); }
a.qf-hub__card:hover .qf-hub__go {
  color: var(--accent);
  transform: translateX(4px);
}
a.qf-hub__card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ── COMING SOON ──────────────────────────────────────────────────────────
   Visually distinct and unmistakably unavailable, WITHOUT relying on colour
   alone: the "Soon" pill is a word, and it is the same word the rail shows.
   The surface drops to --surface-2 so the card reads as inset rather than
   raised, and there is no hover state at all — nothing here responds to a
   pointer, because nothing here is interactive.

   No dashed border, deliberately: the system's border law is 2px solid, and a
   second border STYLE is as much a new primitive as a second accent hue. */
.qf-hub__card--soon {
  background: var(--surface-2);
  border-color: var(--surface-3);
  padding-right: 16px;
  cursor: default;
}
.qf-hub__card--soon .qf-hub__card-t { color: var(--ink-soft); }
.qf-hub__card--soon .qf-hub__card-d { color: var(--muted); }

.qf-hub__soon {
  align-self: flex-start;
  margin-top: 8px;
  padding: 0 8px;
  border: 2px solid var(--border-strong);
  border-radius: var(--radius-btn);
  font-size: 11px;
  font-weight: 600;
  line-height: 20px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--surface);
}

/* ── The loose links at the foot — the rail's own two, same idiom. ──────── */
.qf-hub__footlinks {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 48px;
  padding-top: 24px;
  border-top: 2px solid var(--surface-3);
}

.qf-hub__loose {
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 400;
  color: var(--muted);
  text-decoration: none;
  transition: background-color var(--qf-dur-fast, 140ms) var(--qf-ease, cubic-bezier(.2, .7, .2, 1));
}
.qf-hub__loose:hover { background: var(--accent-soft); color: var(--accent); }
.qf-hub__loose:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* ── Desktop: clear the permanent rail ────────────────────────────────────
   Same breakpoint and same width token the rail itself uses, so the two can
   only ever agree. `--tp-w` is declared on :root by tool-portal.css, which
   this host always loads alongside this file. */
@media (min-width: 1024px) {
  .qf-hub {
    padding-left: 32px;
    padding-right: 32px;
  }
  .qf-hub__title { font-size: 40px; }
}

/* ── Narrow: the grid is already one column here; only the type steps down. */
@media (max-width: 480px) {
  .qf-hub { padding-top: 24px; }
  .qf-hub__title { font-size: 28px; }
  .qf-hub__intro { margin-bottom: 32px; }
  .qf-hub__group { margin-top: 32px; }
}

/* THE 300px GRID FLOOR IS TALLER THAN A 320px VIEWPORT'S CONTENT BOX.
   At 320px the page has 288px of content width after its 16px gutters, so a
   `minmax(300px, 1fr)` track overflows it by 12px and the page scrolls
   sideways — the one defect this layout could introduce. `minmax(0, 1fr)`
   below that width keeps the single column inside the box. */
@media (max-width: 360px) {
  .qf-hub__grid { grid-template-columns: minmax(0, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  .qf-hub__card,
  .qf-hub__go,
  .qf-hub__loose { transition: none; }
  a.qf-hub__card:hover .qf-hub__go { transform: none; }
}
