/* ═══════════════════════════════════════════════════════════════════════════
   The widget library, on the Wabi glass.

   ⚠ THE GROUND IS #f0f0f0 AND THE CHROME FLOATS ON IT. wabi.ai is a pale page
   with one pill of real glass over it — not a dark dashboard with a toolbar
   welded to the top — and that difference is most of what makes a page read as
   Wabi. The glass here is the PORT in css/wabi.css, never an approximation:
   the same inset pair, the same conic edge, the same travelling shine.

   ⚠ AND `.chip` MEANT TWO THINGS. app.css's composer chip is a fixed 56pt
   square with overflow:hidden, so every filter here once rendered as a 56px
   box with its name clipped inside it. The filters are `.cchip` / `.pchip`.
   ═══════════════════════════════════════════════════════════════════════════ */

body.lib{
  margin:0;min-height:100vh;
  background:
    radial-gradient(60% 42% at 78% -6%, rgba(255,255,255,.9), transparent 62%),
    radial-gradient(52% 40% at 8% 4%, rgba(255,255,255,.72), transparent 60%),
    var(--paper);
  color:var(--ink);
  font:400 15px/1.5 Selecta, ui-sans-serif, system-ui, sans-serif;
  -webkit-font-smoothing:antialiased;
}

/* ── the masthead ───────────────────────────────────────────────────────── */
/* ⚠ GLASS OVER A FLAT GROUND IS NOT GLASS. The whole header was sticky, so the
   title travelled down the page with the bar — eating a third of the screen —
   and nothing ever passed UNDERNEATH the bar, which is the one thing a
   backdrop-filter needs to do anything at all. Over #f0f0f0 with nothing behind
   it the panel read as a plain pale card. The title scrolls away and the BAR
   stays, and the moment ninety widgets start sliding under it the material
   turns on: the blur has something to blur, the saturate has colour to lift,
   and the conic edge catches a real edge. Same CSS, one word moved. */
#lhead{padding:38px 30px 0}
#bar{position:sticky;top:12px;z-index:40;margin:0 30px}
#lhead .mast{display:flex;gap:18px;align-items:flex-start;max-width:1560px;margin:0 auto 22px}
#lhead .home{
  flex:none;width:44px;height:44px;border-radius:50%;margin-top:2px;
  display:grid;place-items:center;text-decoration:none;
  background:rgba(255,255,255,.55);
  box-shadow:inset 0 .5px 0 rgba(255,255,255,.9), 0 2px 8px rgba(25,25,25,.06);
  backdrop-filter:blur(10px) saturate(1.3);-webkit-backdrop-filter:blur(10px) saturate(1.3);
  transition:transform .3s var(--ease-wabi);
}
#lhead .home:hover{transform:scale(.94)}
/* the mark: the app icon's own five orbs, half an orb apart, every other one
   dropped — the same geometry the home screen draws */
#lhead .mark{
  width:22px;height:13px;display:block;
  background:
    radial-gradient(circle at 50% 50%, var(--ink) 49%, transparent 50%) 0 0/9px 9px no-repeat,
    radial-gradient(circle at 50% 50%, var(--ink) 49%, transparent 50%) 4.5px 4px/9px 9px no-repeat,
    radial-gradient(circle at 50% 50%, var(--ink) 49%, transparent 50%) 9px 0/9px 9px no-repeat,
    radial-gradient(circle at 50% 50%, var(--ink) 49%, transparent 50%) 13.5px 4px/9px 9px no-repeat;
}
#lhead h1{margin:0;font-size:32px;font-weight:500;letter-spacing:-.03em}
#lhead .ti p{margin:7px 0 0;max-width:64ch;color:var(--ink-60);font-size:15px}
#lhead .ti p b{font-weight:500;color:var(--ink)}
#lhead .ti a{color:var(--ink);text-decoration-color:var(--ink-40);text-underline-offset:3px}

/* ── the glass bar ──────────────────────────────────────────────────────── */
.glass-bar{
  max-width:1560px;margin:0 auto;padding:12px 14px;border-radius:30px;
  background:linear-gradient(-75deg, rgba(255,255,255,.28), rgba(255,255,255,.62), rgba(255,255,255,.28));
  box-shadow:
    inset 0 .125em .125em rgba(0,0,0,.035),
    inset 0 -.125em .125em rgba(255,255,255,.5),
    0 .25em .125em -.125em rgba(0,0,0,.10),
    0 0 .1em .25em inset rgba(255,255,255,.2);
  backdrop-filter:blur(16px) saturate(1.5);-webkit-backdrop-filter:blur(16px) saturate(1.5);
  position:relative;
}
/* the conic edge, exactly as the glass button carries it */
.glass-bar::after{
  content:'';position:absolute;inset:-1px;border-radius:31px;padding:1px;box-sizing:border-box;
  background:
    conic-gradient(from -75deg at 50% 50%,
      rgba(0,0,0,.32), rgba(0,0,0,0) 5% 40%, rgba(0,0,0,.32) 50%, rgba(0,0,0,0) 60% 95%, rgba(0,0,0,.32)),
    linear-gradient(180deg, rgba(255,255,255,.5), rgba(255,255,255,.5));
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
  pointer-events:none;
}
.glass-bar .row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.glass-bar .row.rails{margin-top:10px;flex-direction:column;align-items:stretch;gap:7px}

.find{position:relative;flex:1;max-width:320px;display:flex;align-items:center}
.find svg{position:absolute;left:13px;width:15px;height:15px;color:var(--ink-40);pointer-events:none}
.find input{
  width:100%;box-sizing:border-box;height:38px;padding:0 14px 0 34px;
  border-radius:19px;border:0;background:rgba(255,255,255,.55);color:var(--ink);
  box-shadow:inset 0 1px 2px rgba(25,25,25,.06), inset 0 0 0 1px rgba(255,255,255,.7);
  font:inherit;font-size:14.5px;outline:none;
}
.find input::placeholder{color:var(--ink-40)}
.find input:focus{background:rgba(255,255,255,.82);box-shadow:inset 0 1px 2px rgba(25,25,25,.06), 0 0 0 2px rgba(25,25,25,.10)}

.seg{display:flex;gap:2px;padding:3px;border-radius:19px;background:rgba(255,255,255,.42);
  box-shadow:inset 0 1px 2px rgba(25,25,25,.05), inset 0 0 0 1px rgba(255,255,255,.6)}
.seg button{
  border:0;background:none;color:var(--ink-60);font:inherit;font-size:13.5px;
  padding:0 15px;height:30px;border-radius:16px;cursor:pointer;
  transition:all .3s var(--ease-wabi);
}
.seg button:hover{color:var(--ink)}
.seg button[aria-pressed="true"]{
  background:#fff;color:var(--ink);font-weight:500;
  box-shadow:0 1px 3px rgba(25,25,25,.12), 0 0 0 .5px rgba(25,25,25,.06);
}
.ghostbtn{
  margin-left:auto;height:38px;padding:0 18px;border-radius:19px;border:0;cursor:pointer;
  display:inline-flex;align-items:center;gap:7px;
  background:var(--ink);color:#fff;font:inherit;font-size:13.5px;font-weight:500;
  transition:transform .3s var(--ease-wabi);
}
.ghostbtn .sh{width:15px;height:15px;flex:none;display:none}
.ghostbtn:hover{transform:scale(.96)}

#cats,#whos{display:flex;gap:6px;flex-wrap:wrap}
.cchip,.pchip{
  display:inline-flex;align-items:center;gap:7px;
  height:31px;padding:0 13px;border-radius:16px;border:0;cursor:pointer;white-space:nowrap;
  background:rgba(255,255,255,.50);color:var(--ink-60);font:inherit;font-size:13px;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.66), 0 1px 2px rgba(25,25,25,.04);
  transition:all .25s var(--ease-wabi);
}
.cchip em,.pchip em{font-style:normal;color:var(--ink-40);font-size:11.5px;font-variant-numeric:tabular-nums}
.cchip:hover,.pchip:hover{background:rgba(255,255,255,.86);color:var(--ink)}
.cchip[aria-pressed="true"],.pchip[aria-pressed="true"]{
  background:var(--ink);color:#fff;box-shadow:0 2px 6px rgba(25,25,25,.22);
}
.cchip[aria-pressed="true"] em,.pchip[aria-pressed="true"] em{color:rgba(255,255,255,.55)}
.pchip .orb{width:13px;height:13px;border-radius:50%;flex:none;
  background:linear-gradient(140deg,var(--o1),var(--o2));box-shadow:0 0 0 1px rgba(255,255,255,.6)}

/* ── the shelf ──────────────────────────────────────────────────────────── */
#grid{max-width:1560px;margin:0 auto;padding:22px 30px 90px}
/* ⚠ a sticky bar eats the top of anything scrolled to */
#grid h2,#grid section{scroll-margin-top:150px}
.sec{margin:0 0 36px}
.sec > h2{
  margin:0 0 14px;font-size:12.5px;font-weight:500;
  letter-spacing:.16em;text-transform:uppercase;color:var(--ink-40);
  display:flex;align-items:baseline;gap:10px;
}
.sec > h2::after{content:'';flex:1;height:1px;background:var(--ink-14)}
.sec > h2 i{font-style:normal;font-variant-numeric:tabular-nums}
.row2{display:grid;gap:24px 20px;grid-template-columns:repeat(auto-fill,minmax(var(--col,158px),1fr))}
body.lib[data-size="56"] .row2{--col:92px;gap:20px 16px}
body.lib[data-size="240"] .row2{--col:240px;gap:28px 22px}

.lw{display:block;border:0;background:none;padding:0;text-align:left;cursor:pointer;color:inherit;font:inherit}
/* ⚠ THE SHADOW BELONGS TO css/depth.css AND ONLY TO IT. This rule used to
   carry its own, and depth.css loads FIRST — so at equal specificity the tile
   kept a shadow the panel had switched off, and every shadow style rendered
   with this one underneath it. Two authors for one property is two answers,
   and the one that wins is whichever file the <link> tags happen to order. */
.lw .hold{
  display:block;position:relative;width:100%;aspect-ratio:1;
  border-radius:22px;overflow:hidden;isolation:isolate;
  transition:transform .28s var(--ease-wabi), box-shadow .28s var(--ease-wabi), filter .28s var(--ease-wabi);
}

/* the hover lift lives in depth.css too — it is the same shadow, further off
   the page, and it has to scale with whatever strength is set */
.lw:focus-visible .hold{outline:2px solid var(--ink);outline-offset:3px}
.lw .hold .field{position:absolute;left:0;top:0;transform-origin:0 0}
.lw cite{display:block;margin:10px 0 0;font-style:normal;font-size:13.5px;font-weight:500;letter-spacing:-.014em}
.lw small{display:block;margin-top:1px;font-size:11.5px;color:var(--ink-40)}
body.lib[data-size="56"] .lw cite{font-size:12px;margin-top:7px}
body.lib[data-size="56"] .lw small{display:none}
.none{color:var(--ink-60);padding:40px 0 90px;font-size:15px}
#lfoot{max-width:1560px;margin:0 auto;padding:0 30px 60px;color:var(--ink-40);font-size:12.5px}

/* ── one widget, up close ───────────────────────────────────────────────── */
#detail{position:fixed;inset:0;z-index:60;display:grid;place-items:center;padding:24px}
#detail[hidden]{display:none}
#detail .scrim{position:absolute;inset:0;border:0;cursor:default;
  background:rgba(240,240,240,.68);backdrop-filter:blur(18px) saturate(1.2)}
#detail .card{
  position:relative;display:grid;grid-template-columns:288px minmax(0,1fr);
  gap:30px;align-items:start;max-width:800px;width:100%;padding:30px;
  border-radius:34px;
  background:linear-gradient(-75deg, rgba(255,255,255,.62), rgba(255,255,255,.92), rgba(255,255,255,.62));
  box-shadow:
    inset 0 .125em .125em rgba(0,0,0,.03),
    inset 0 -.125em .125em rgba(255,255,255,.6),
    0 30px 70px rgba(25,25,25,.16), 0 0 0 1px rgba(255,255,255,.7);
  backdrop-filter:blur(20px) saturate(1.5);-webkit-backdrop-filter:blur(20px) saturate(1.5);
}
#detail .big{position:relative;width:240px;height:240px;border-radius:32px;overflow:hidden;isolation:isolate;
  box-shadow:0 0 0 1px rgba(25,25,25,.07), 0 14px 34px rgba(25,25,25,.16)}
#detail .big .field{position:absolute;left:0;top:0;transform-origin:0 0}
#detail .meta{min-width:0}
#detail .from{display:block;font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-40)}
#detail [data-name]{display:block;margin:5px 0 0;font-size:28px;font-weight:500;letter-spacing:-.03em}
#detail .prompt{margin:12px 0 0;font-size:15px;line-height:1.55;color:var(--ink-60)}
#detail h3{margin:22px 0 8px;font-size:11.5px;font-weight:400;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-40)}
/* ⚠ eighteen chips do not fit — the row scrolls, and it snaps */
#detail .vars{
  display:flex;gap:6px;margin:18px -30px 0;padding:0 30px;
  overflow-x:auto;scroll-snap-type:x proximity;scroll-padding-left:30px;scrollbar-width:none;
}
#detail .vars::-webkit-scrollbar{display:none}
.vchip{
  flex:none;scroll-snap-align:start;white-space:nowrap;cursor:pointer;
  border:0;background:rgba(255,255,255,.62);color:var(--ink-60);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.7), 0 1px 2px rgba(25,25,25,.05);
  font:inherit;font-size:12.5px;padding:0 13px;height:31px;border-radius:16px;
  transition:all .25s var(--ease-wabi);
}
.vchip:hover{background:#fff;color:var(--ink)}
.vchip[aria-pressed="true"]{background:var(--ink);color:#fff;font-weight:500}
#detail .adds{display:flex;flex-direction:column;gap:5px}
#detail .adds span{font-size:13.5px;color:var(--ink-60);padding-left:15px;position:relative}
#detail .adds span::before{content:'+';position:absolute;left:0;color:var(--ink-40)}
#detail .owners{display:flex;align-items:center;gap:6px;margin-top:20px;padding-top:16px;
  border-top:1px solid var(--ink-14);font-size:12.5px;color:var(--ink-40)}
#detail .owners .orb{width:15px;height:15px;border-radius:50%;background:linear-gradient(140deg,var(--o1),var(--o2))}
#detail .owners span{margin-left:5px}
#detail .shut{
  position:absolute;right:16px;top:16px;z-index:2;width:34px;height:34px;border-radius:50%;
  border:0;cursor:pointer;display:grid;place-items:center;
  background:rgba(255,255,255,.7);box-shadow:inset 0 0 0 1px rgba(255,255,255,.8), 0 1px 3px rgba(25,25,25,.10);
  transition:transform .25s var(--ease-wabi);
}
#detail .shut:hover{transform:scale(.92)}
#detail .shut::before,#detail .shut::after{content:'';position:absolute;width:13px;height:1.5px;background:var(--ink);border-radius:1px}
#detail .shut::before{transform:rotate(45deg)}
#detail .shut::after{transform:rotate(-45deg)}

@media (max-width:820px){
  #lhead{padding:22px 16px 0}
  #lhead h1{font-size:24px}
  #lhead .ti p{font-size:14px}
  #grid,#lfoot{padding-left:16px;padding-right:16px}
  .row2{--col:132px;gap:18px 14px}
  #bar{margin:0 16px}
  .glass-bar{border-radius:24px}
  .ghostbtn{margin-left:0}
}

/* ── the bar, on a phone ─────────────────────────────────────────────────────
   ⚠ A WRAPPING FILTER BAR IS TALLER THAN THE PHONE. Fourteen category chips and
   eight people wrap to seven rows at 390pt, so the bar came out 800px tall on
   an 844px screen: the library opened on its own controls and you had to scroll
   past all of them to reach a single widget — and because the bar is STICKY it
   then followed you down the page and covered it.

   The rails scroll sideways instead of wrapping. That is the phone answer to a
   long row of chips and it is the app's own idiom already — the variant chips
   under an opened widget do exactly this. ⚠ AND A `start` SNAP IGNORES
   `padding-inline` AND CANCELS IT, so a scroller inset by the bar's padding
   pulls its first chip flush to the edge and reads as CROPPED; `scroll-padding`
   is what gives it back. */
@media (max-width:640px){
  #lhead{padding:18px 14px 0}
  #lhead .mast{gap:12px;margin-bottom:16px}
  #lhead h1{font-size:21px}
  #lhead .ti p{font-size:13.5px;line-height:1.45}
  #lhead .home{width:38px;height:38px}
  #bar{margin:0 14px;top:8px}
  .glass-bar{padding:9px 10px;border-radius:22px}
  .glass-bar .row{gap:7px;flex-wrap:nowrap}
  .glass-bar .row.rails{margin-top:8px;gap:6px}
  .find{max-width:none;min-width:0;flex:1 1 0}
  .find input{font-size:14px}
  .seg{flex:none}
  .seg button{padding:0 10px;font-size:12.5px}
  .ghostbtn{flex:none;padding:0 13px;font-size:12.5px}
  /* one line each, and they scroll */
  #cats,#whos{
    flex-wrap:nowrap;overflow-x:auto;overscroll-behavior-x:contain;
    scroll-snap-type:x proximity;
    margin-inline:-10px;padding-inline:10px;scroll-padding-inline:10px;
    scrollbar-width:none;-ms-overflow-style:none;
  }
  #cats::-webkit-scrollbar,#whos::-webkit-scrollbar{display:none}
  #cats[data-more~="r"],#whos[data-more~="r"]{
    -webkit-mask:linear-gradient(90deg,#000 calc(100% - 26px),transparent);
            mask:linear-gradient(90deg,#000 calc(100% - 26px),transparent);
  }
  #cats[data-more="lr"],#whos[data-more="lr"]{
    -webkit-mask:linear-gradient(90deg,transparent,#000 22px,#000 calc(100% - 26px),transparent);
            mask:linear-gradient(90deg,transparent,#000 22px,#000 calc(100% - 26px),transparent);
  }
  #cats[data-more="l"],#whos[data-more="l"]{
    -webkit-mask:linear-gradient(90deg,transparent,#000 22px);
            mask:linear-gradient(90deg,transparent,#000 22px);
  }
  #cats > *,#whos > *{scroll-snap-align:start;flex:none}
  .cchip,.pchip{height:29px;padding:0 11px;font-size:12.5px;gap:6px}
  #grid,#lfoot{padding-left:14px;padding-right:14px}
  #grid h2,#grid section{scroll-margin-top:120px}
  .row2{--col:124px;gap:16px 12px}
}

/* ⚠ AND AT 320pt THE THREE CONTROLS ARE WIDER THAN THE ROW. Search, the size
   segment and Shuffle come to 310px inside a 272px bar, so the search field
   was squeezed to a bare magnifier with no room to type in — a control that
   renders and cannot be used. Shuffle keeps its meaning as a picture, so below
   400 it is the icon alone and the other two get their width back. */
@media (max-width:400px){
  .seg button{padding:0 8px;font-size:12px}
  .find{min-width:106px}
  .ghostbtn{padding:0;width:34px;height:34px;justify-content:center;border-radius:17px}
  .ghostbtn .sh{display:block}
  .ghostbtn span{display:none}
  .glass-bar .row{gap:6px}
  #detail .card{grid-template-columns:minmax(0,1fr);gap:20px;padding:22px}
  #detail .big{width:100%;height:auto;aspect-ratio:1}
  #detail .vars{margin-inline:-22px;padding-inline:22px;scroll-padding-left:22px}
}
@media (prefers-reduced-motion:reduce){ .lw .hold{transition:none} }


/* ── only what you are looking at ────────────────────────────────────────────
   ⚠ NINETY LIVE WIDGETS IS NINETY DRAWS A FRAME, and on a page you SCROLL
   almost none of them is being looked at. js/library.js draws only the tile
   under the pointer; these three are the ones the BROWSER animates without
   asking JS — a keyframe keeps running on a compositor thread whether or not
   anybody can see it, so they are paused with everything else and released
   under the pointer. */
@media (hover: hover) {
  #grid [data-w] .field *{animation-play-state:paused}
  #grid [data-w]:hover .field *{animation-play-state:running}
}

/* ⚠ THE HAND-ROLLED DEPTH PANEL IS GONE, not kept beside DialKit. Two
   renderers for one description is two things to keep in step, and the whole
   point of moving to DialKit was that twenty controls is not a thing to
   hand-roll — a chip row, five sliders and their readouts, all of it duplicated
   the moment the model grew a layer. */

/* ── only what you are looking at ────────────────────────────────────────────
   ⚠ NINETY LIVE WIDGETS IS NINETY DRAWS A FRAME, and on a page you SCROLL
   almost none of them is being looked at. js/library.js draws only the tile
   under the pointer; these three are the ones the BROWSER animates without
   asking JS — a keyframe keeps running on a compositor thread whether or not
   anybody can see it, so they are paused with everything else and released
   under the pointer. */
@media (hover: hover) {
  #grid [data-w] .field *{animation-play-state:paused}
  #grid [data-w]:hover .field *{animation-play-state:running}
}

/* ── the depth panel ─────────────────────────────────────────────────────────
   ⚠ IT OPENS INSIDE THE BAR, so what it changes stays visible behind it. A
   settings page for a property of ninety tiles is a page you cannot judge the
   setting on. */
/* ── only what you are looking at ────────────────────────────────────────────
   ⚠ NINETY LIVE WIDGETS IS NINETY DRAWS A FRAME, and on a page you SCROLL
   almost none of them is being looked at. js/library.js draws only the tile
   under the pointer; these three are the ones the BROWSER animates without
   asking JS — a keyframe keeps running on a compositor thread whether or not
   anybody can see it, so they are paused with everything else and released
   under the pointer. */
@media (hover: hover) {
  #grid [data-w] .field *{animation-play-state:paused}
  #grid [data-w]:hover .field *{animation-play-state:running}
}

/* ⚠ THE HAND-ROLLED DEPTH PANEL IS GONE, not kept beside DialKit. Two
   renderers for one description is two things to keep in step, and the whole
   point of moving to DialKit was that twenty controls is not a thing to
   hand-roll — a chip row, five sliders and their readouts, all of it duplicated
   the moment the model grew a layer. */

/* ── only what you are looking at ────────────────────────────────────────────
   ⚠ NINETY LIVE WIDGETS IS NINETY DRAWS A FRAME, and on a page you SCROLL
   almost none of them is being looked at. js/library.js draws only the tile
   under the pointer; these three are the ones the BROWSER animates without
   asking JS — a keyframe keeps running on a compositor thread whether or not
   anybody can see it, so they are paused with everything else and released
   under the pointer. */
@media (hover: hover) {
  #grid [data-w] .field *{animation-play-state:paused}
  #grid [data-w]:hover .field *{animation-play-state:running}
}

/* ── the depth panel ─────────────────────────────────────────────────────────
   ⚠ IT OPENS INSIDE THE BAR, so what it changes stays visible behind it. A
   settings page for a property of ninety tiles is a page you cannot judge the
   setting on. */
