/* ─────────────────────────────────────────────────────────────────────────────
   io-areas-landing.html's own sheet — the whole `.al-*` card vocabulary and its own dark page tokens.

   The source's own bytes, unedited, so a diff against the original is a diff of
   markup only. Linked by the page whose site.pages.stylesheet names it — see
   app/(area)/areas/[slug]/page.tsx for why this is per PAGE and not per route
   group.
   carried by 1 page(s)
   ──────────────────────────────────────────────────────────────────────────── */


/* ============================================================
   EVERY IO AREA — the index, on its own
   ============================================================
   The "Every IO area" section from io-area-headings.html, lifted out as a page
   of its own, with one change asked for: the area cells are no longer a row of
   names. They are cards the size of the LEAD CARD from that file's rails — the
   one that holds still at the left of each rail while the cards scroll past it
   — which is 288px wide and as tall as the rail, 338px.

   THE CARD IS THAT CARD, IN THE DARK SET. Same 288px measure, same internal
   order: an index chip and a state line, the name, a display count, then the
   list. The tones are the ones already declared on `.hb` below, because this
   page is the dark ground the index sat on and a white card dropped onto it
   would be a second design rather than the same one resized.

   Sized at 288x338 and filled rather than stretched: an empty card that size
   reads as a mistake, so each one carries what the lead card carries — that
   area's Agent Libraries with their column-prompt counts. 23 of the 65 have
   none, and those say so.
   ============================================================ */
:root{
  --nav-h:51px;
  /* and the second bar parked under it. It is the same bar again, so it is
     the same height — the stack is --nav-h twice. This is the value the page
     is laid out with before the script runs; once the bar has mounted the
     script overwrites it with what the bar MEASURES, and writes 0 on a page
     that turned out to have nothing worth indexing. */
  --sub-h:51px;
  --ui:-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Inter,Arial,sans-serif;
  --io-display:"Space Grotesk",-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,sans-serif;
  --io-mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
}
/* ============================================================
   THE AREA BAR  (.area-nav)  — the index, as a sticky rail
   ============================================================
   What was a 66-cell matrix under a 64px headline is now a bar that stays at
   the top of the window: the same 65 links, in the same order, scrolling
   sideways instead of wrapping. The prose that introduced the page went with
   it — on a page this long an intro is read once and then scrolled past
   forever, while a way back to any area is wanted the whole way down.

   `position:sticky` and not `fixed`. Fixed would take the bar out of flow and
   the first hero would start underneath it. Sticky keeps its space in the
   document, so the page below begins where it always did.

   THAT IS NOT ENOUGH ON ITS OWN, and the first version of this assumed it was.
   Keeping its space fixes the INITIAL layout; it does nothing for an anchor
   jump, which still scrolls the target to viewport 0 — under the bar. Measured:
   the hero landed at top 0 with the bar's bottom edge at 51. So the heroes
   carry `scroll-margin-top`, off the same `--nav-h` the bar is sized by, and
   the two cannot drift apart.

   It carries `id="top"`, which the "all areas" link on every label band already
   points at, so those 65 links keep working without being touched. */
.area-nav{position:sticky;top:0;z-index:80;display:flex;align-items:stretch;
  background:rgba(10,10,10,.94);backdrop-filter:blur(14px);
  border-bottom:1px solid #272727;
  font-family:"IBM Plex Sans",system-ui,-apple-system,sans-serif}
.an-brand{flex:none;display:flex;align-items:center;gap:9px;padding:0 18px 0 24px;
  font:600 13px/1 "Space Grotesk",system-ui,sans-serif;letter-spacing:-.01em;color:#fff;
  border-right:1px solid #272727;white-space:nowrap}
.an-brand em{font-style:italic;font-weight:500;color:#FF9013}
.an-brand b{font:600 10px/1 var(--io-mono);letter-spacing:.1em;color:#7A7A7A;
  border:1px solid #272727;border-radius:20px;padding:4px 8px}

/* the viewport, with the two fades that say there is more either way */
.an-vp{position:relative;flex:1;min-width:0}
.an-vp::before,.an-vp::after{content:"";position:absolute;top:0;bottom:0;width:44px;
  pointer-events:none;z-index:3}
.an-vp::before{left:0;background:linear-gradient(90deg,rgba(10,10,10,.94),transparent)}
.an-vp::after{right:0;background:linear-gradient(270deg,rgba(10,10,10,.94),transparent)}

.an-scroll{display:flex;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;
  -webkit-overflow-scrolling:touch;scroll-snap-type:x proximity}
.an-scroll::-webkit-scrollbar{display:none}

/* ---- the bar, made endless ---------------------------------------
   Two properties have to be off for the wrap in the script below to
   stay invisible. A proximity snap would re-aim the bar in the frame
   right after a wrap, and a smooth scroll-behaviour would animate the
   wrap itself — either one turns a seam nobody can see into a visible
   twitch. `overscroll-behavior-x` keeps a trackpad swipe that runs on
   past the chips from being read as a browser Back. */
.an-scroll.an-loop{scroll-snap-type:none;scroll-behavior:auto;overscroll-behavior-x:contain}
.an-scroll.an-loop .an{scroll-snap-align:none}

/* ---- and made to read as a ring ----------------------------------
   Endless is a fact about the scroll; a ring is a thing you can see.
   So the chips no longer stop dead at the two edges — they turn away
   from you and go round the back.

   Each chip carries its OWN `perspective()` rather than the bar
   carrying one for all of them. It has to: `overflow-x:auto` on the
   scroller forces `transform-style:flat`, so a single shared 3D space
   is not available here. At a chip's size the difference between one
   projection and 65 is not visible — what you read either way is a
   surface curving off.

   The angle per chip is written by the script, off how near an edge
   it is. What the stylesheet owns is the axis it turns about and the
   two fades — widened from 44px to the depth of the turn, so the far
   side of the ring dissolves into the bar's own black instead of
   being sliced flat by the edge of it. */
.an-scroll.an-ring .an{transform-origin:50% 50%}
.an-vp.an-ring::before,.an-vp.an-ring::after{width:150px}
.an-vp.an-ring::before{background:linear-gradient(90deg,#0A0A0A 4%,rgba(10,10,10,.55) 40%,transparent 82%)}
.an-vp.an-ring::after{background:linear-gradient(270deg,#0A0A0A 4%,rgba(10,10,10,.55) 40%,transparent 82%)}

.an{flex:none;scroll-snap-align:start;display:flex;flex-direction:column;gap:5px;
  justify-content:center;padding:11px 16px;border-right:1px solid #1F1F1F;
  text-decoration:none;white-space:nowrap;
  box-shadow:inset 0 0 0 0 #FF9013;transition:background .15s,box-shadow .15s}
.an:hover{background:#151515;box-shadow:inset 0 -2px 0 0 #FF9013}
.an-n{font:400 9.5px/1 var(--io-mono);letter-spacing:.1em;color:#5A5A5A}
.an:hover .an-n{color:#FF9013}
.an-t{font:600 13.5px/1 "Space Grotesk",system-ui,sans-serif;letter-spacing:-.015em;color:#fff}
/* the one rule that matters: only the mark is orange, and it is italic */
.an-t em{font-style:italic;font-weight:500;color:#FF9013}

/* ---- the second bar: the first bar, mounted again ----
   What used to sit here was a different bar — its own ground, its own chip,
   its own two type sizes, half the height of the one above it and a ticker
   that drove itself sideways. Two bars that are not the same bar have to be
   kept the same by hand, and were not: the chip up top carried its number
   above its name, the chip down here carried it beside; the mark was #FF9013
   up top and #C97A28 down here. That is all gone, and what replaces it is
   the bar above, MOUNTED A SECOND TIME.

   So this rule is two lines long, and that is the point of it. The second
   bar carries `.area-nav` and its chips carry `.an`, which means every rule
   above already describes it — the black ground and its blur, the brand cell
   and its count, the number over the name, the mark in orange italic, the
   underline on hover, the endless strip and the ring it bends into at both
   ends. Nothing here restates any of that, so nothing here can drift from it.

   What is actually different about the second bar is two numbers and a feed:
   it parks against the first one's underside rather than the top of the
   window, it sits one step below it in the stack, and where the bar above is
   the same 65 links on every page of this site, this one is built at load out
   of whatever sections the page it is on actually has. The feed is the
   script's business; the two numbers are this rule.

   The two bars are therefore the same height, and the sticky stack is
   `--nav-h` twice — which is what every anchor below clears. A page with
   nothing worth indexing mounts no second bar, and the script sets `--sub-h`
   to 0 so those anchors do not clear a bar that is not there. */
.area-nav.is-sub{top:var(--nav-h);z-index:79}

/* And everything the second bar points at clears both of them.

   Two rules below already give that clearance to the heroes and the label
   bands, because until now those were the only things anything linked to.
   The second bar links to whatever the page is made of — a panel, a rail, a
   named row inside a rail — and none of that had ever been a scroll target,
   so a chip scrolled its section to the top of the WINDOW and both bars sat
   on top of it. Measured on Context IO: Agent Libraries landed at 0 with
   102px of bar over it.

   Keyed to the attribute the script writes as it indexes a section, rather
   than to a list of the classes it happens to index today. The bar and the
   clearance are then the same decision made once: anything that gets a chip
   gets the offset, and a shape added to the table of contents tomorrow
   cannot arrive without it. */
[data-toc]{scroll-margin-top:calc(var(--nav-h) + var(--sub-h))}

/* There is no arrival animation here, and that is deliberate. A new page
   brings a new set of chips in the second bar, and this used to fade them
   up over a third of a second to say so. The arrival is now a MOVEMENT —
   the script runs both strips in horizontally from where the click that
   brought you here left them — and a fade happening at the same time is a
   second thing to watch during the one moment the bars are asking to be
   read. One motion, in one direction, and nothing else. */

/* what the bar costs every anchor on the page */
.hb .fl-hero{scroll-margin-top:calc(var(--nav-h) + var(--sub-h))}
.blab{scroll-margin-top:calc(var(--nav-h) + var(--sub-h))}

@media(max-width:760px){
  :root{--nav-h:47px;--sub-h:47px}
  .an-brand{padding:0 12px 0 16px;font-size:12px}
  .an-brand b{display:none}
  .an{padding:9px 13px}
  .an-t{font-size:12.5px}
}


/* the chip for the page you are on */
.an[aria-current="page"]{background:#151515;box-shadow:inset 0 -2px 0 0 #FF9013}
.an[aria-current="page"] .an-n{color:#FF9013}
.an-brand{text-decoration:none}
.an-brand:hover em{color:#FF7A00}

/* the mark, in front of the wordmark — its own link, back to the areas landing page */
.an-home{flex:none;display:flex;align-items:center;padding:0 0 0 20px;
  text-decoration:none;line-height:0}
.an-home svg{display:block;width:22px;height:22px;
  transition:opacity .15s ease,transform .15s ease}
.an-home:hover svg{opacity:.85;transform:scale(1.06)}
.an-home + .an-brand{padding-left:10px}
@media(max-width:760px){
  .an-home{padding-left:14px}
  .an-home svg{width:19px;height:19px}
  .an-home + .an-brand{padding-left:8px}
}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
img{max-width:100%;display:block}

/* the token set, verbatim from io-area-headings.html */
body{
  --font-sans:"IBM Plex Sans",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --font-mono:"IBM Plex Mono",ui-monospace,"SF Mono",monospace;
  --font-display:"Space Grotesk","IBM Plex Sans",system-ui,sans-serif;

  --wf-brand:#FF9013;--wf-brand-glow:rgba(255,144,19,.06);
  --wf-bg:#0A0A0A;--wf-bg-sunken:#060606;
  --wf-surface:#151515;--wf-surface-2:#1C1C1C;
  --wf-fg:#FFFFFF;--wf-fg-muted:#B4B4B4;--wf-fg-subtle:#7A7A7A;--wf-fg-faint:#5A5A5A;
  --wf-border:#272727;--wf-border-strong:#3A3A3A;--wf-border-subtle:#1F1F1F;
  --io-accent:#FF9013;--io-accent-2:#FF4C29;--io-accent-soft:rgba(255,144,19,.12);

  background:var(--wf-bg);color:var(--wf-fg);
  font-family:var(--font-sans);font-size:16px;line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
a{color:inherit;text-decoration:none}
h1,h2{font-family:var(--font-display);letter-spacing:-.02em}
.container{max-width:1360px;margin:0 auto;padding:0 24px}

/* ---- the head, as it reads on the source page ---- */
.io-index{padding:96px 0 104px;position:relative}
.fl-eyebrow{font-family:var(--font-mono);font-size:12px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--wf-fg-subtle);text-align:center}
.fl-h2{font-family:var(--font-display);font-size:clamp(38px,5vw,64px);font-weight:700;
  letter-spacing:-.03em;line-height:1.02;color:var(--wf-fg);text-align:center;margin-top:14px}
.fl-h2 em{font-style:italic;font-weight:500;color:var(--io-accent)}
.fl-lead{max-width:640px;margin:20px auto 0;text-align:center;color:var(--wf-fg-muted);
  font-size:18px;line-height:1.55}

/* ---- the grid ----
   288px columns, centred, so the cards keep the lead card's exact measure at
   every width and the row simply holds fewer of them. `auto-fill` rather than
   `auto-fit`: auto-fit would stretch the last row's cards to fill the track and
   the whole point is that they stay 288. */
.al-grid{display:grid;grid-template-columns:repeat(auto-fill,288px);gap:16px;
  justify-content:center;margin-top:52px}

/* ---- the card: the lead card, in the dark set ---- */
.al-card{position:relative;overflow:hidden;height:338px;
  background:linear-gradient(160deg,var(--wf-surface),var(--wf-bg-sunken));
  border:1px solid var(--wf-border);border-radius:10px;
  padding:15px 16px 14px;display:flex;flex-direction:column;gap:11px;
  box-shadow:0 1px 3px rgba(0,0,0,.4),0 14px 32px -18px rgba(0,0,0,.6);
  transition:border-color .16s cubic-bezier(.4,0,.2,1),transform .16s cubic-bezier(.4,0,.2,1)}
.al-card::before{content:"";position:absolute;inset:0;pointer-events:none;opacity:.5;
  background-image:linear-gradient(var(--wf-brand-glow) 1px,transparent 1px),
                   linear-gradient(90deg,var(--wf-brand-glow) 1px,transparent 1px);
  background-size:26px 26px;
  mask-image:radial-gradient(ellipse 120% 70% at 100% 0%,#000,transparent 72%);
  -webkit-mask-image:radial-gradient(ellipse 120% 70% at 100% 0%,#000,transparent 72%)}
.al-card::after{content:"";position:absolute;top:-60px;right:-60px;width:150px;height:150px;
  border-radius:50%;background:radial-gradient(circle,var(--io-accent-soft),transparent 68%);
  pointer-events:none}
.al-card > *{position:relative;z-index:2}
.al-card:hover{border-color:var(--wf-brand);transform:translateY(-3px)}

.al-top{display:flex;align-items:center;gap:8px}
.al-idx{font:700 8.5px/1 var(--io-mono);letter-spacing:.18em;text-transform:uppercase;
  color:var(--io-accent);border:1px solid rgba(255,144,19,.26);background:rgba(255,144,19,.10);
  padding:4px 8px;border-radius:4px}
.al-state{margin-left:auto;display:inline-flex;align-items:center;gap:5px;
  font:700 8px/1 var(--io-mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--wf-fg-subtle)}
.al-state i{width:5px;height:5px;border-radius:50%;background:var(--io-accent);
  box-shadow:0 0 0 3px rgba(255,144,19,.16);flex:none}
.al-name{font:600 16px/1.22 var(--io-display);letter-spacing:-.012em;color:var(--wf-fg)}
.al-name em{font-style:italic;font-weight:500;color:var(--io-accent)}
.al-count{font:700 29px/1 var(--io-display);color:var(--io-accent);letter-spacing:-.028em}
.al-count small{font:500 9px/1 var(--io-mono);color:var(--wf-fg-subtle);letter-spacing:.11em;
  text-transform:uppercase;margin-left:6px}

.al-rows{display:flex;flex-direction:column;gap:1px;background:var(--wf-border-subtle);
  border:1px solid var(--wf-border-subtle);border-radius:7px;overflow:hidden;
  min-height:0;margin-bottom:auto}
.al-row{display:block;background:var(--wf-surface-2);padding:8px 10px}
.al-rt{display:flex;align-items:center;gap:7px}
.al-rt svg{width:11px;height:11px;color:var(--io-accent);flex:none}
.al-k{font:400 10.5px/1.35 var(--ui);color:var(--wf-fg-muted);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;min-width:0}
.al-v{margin-left:auto;font:700 10px/1 var(--io-mono);color:var(--wf-fg-subtle);flex:none}
.al-more .al-k{color:var(--wf-fg-faint);font-style:italic}
.al-empty{background:transparent;border-style:dashed;border-color:var(--wf-border);
  padding:12px;display:flex;align-items:center;justify-content:center;text-align:center}
.al-note{font:400 10.5px/1.5 var(--ui);color:var(--wf-fg-faint);max-width:150px}

/* The strip along the bottom. It is the footer the lead card carried before the
   filters took its room, and here it does a second job: five libraries do not
   fill 338px, and a card with a hole under its list reads as unfinished. */
.al-foot{display:flex;align-items:center;gap:8px;padding:9px 11px;border-radius:7px;
  border:1px dashed rgba(255,144,19,.26);background:rgba(255,144,19,.07);margin-top:auto}
.al-fk{font:700 8px/1 var(--io-mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--wf-fg-subtle)}
.al-fv{margin-left:auto;font:700 10.5px/1 var(--io-mono);color:var(--io-accent);letter-spacing:.04em}
.al-foot-q{border-color:var(--wf-border);background:transparent}
.al-foot-q .al-fv{color:var(--wf-fg-subtle)}

footer{padding:0 0 64px;text-align:center;color:var(--wf-fg-faint);
  font:400 12.5px/1.6 var(--io-mono);letter-spacing:.04em}

@media(max-width:760px){
  .io-index{padding:64px 0 72px}
  .al-grid{grid-template-columns:288px;margin-top:38px}
}
