/* layout — app shell. Mobile-first: topbar + scroll body + bottom tabbar.
 * At >=1024px the topic drawer becomes a permanent left rail and the tabbar
 * dissolves into it, because a pointer user has no thumb zone to respect. */

/* ---------- topbar: search + settings, nothing else ---------- */
.topbar{
  position:fixed; inset:0 0 auto 0; z-index:30;
  height:calc(var(--bar-h) + env(safe-area-inset-top));
  padding:env(safe-area-inset-top) var(--space-xs) 0;
  display:flex; align-items:center; gap:var(--space-2xs);
  background:var(--color-bar); border-bottom:var(--rule-hair) solid var(--color-rule);
  -webkit-backdrop-filter:blur(14px) saturate(180%); backdrop-filter:blur(14px) saturate(180%);
}

/* ---------- main reading column ---------- */
.shell{
  padding-top:calc(var(--bar-h) + env(safe-area-inset-top));
  padding-bottom:calc(var(--tabbar-h) + env(safe-area-inset-bottom));
}
.content{
  max-width:1040px; margin-inline:auto;
  padding:var(--space-md) var(--space-sm) var(--space-2xl);
}

/* ---------- topic rail — off-canvas drawer on small screens ---------- */
.rail{
  position:fixed; inset:0 auto 0 0; z-index:50;
  width:min(84%,320px); display:flex; flex-direction:column;
  background:var(--color-paper-2);
  border-right:var(--rule-hair) solid var(--color-rule);
  transform:translateX(0); transition:transform var(--dur-mid) var(--ease-out);
}
/* [hidden] is overridden to keep the slide transition, so visibility does the
   real hiding — it takes the panel out of the tab order and a11y tree once the
   slide finishes, which display:none can't do mid-transition. */
.rail[hidden]{
  display:flex; transform:translateX(-101%); pointer-events:none;
  visibility:hidden; transition:transform var(--dur-mid) var(--ease-in),
                                visibility 0s linear var(--dur-mid);
}
.rail-scroll{overflow-y:auto; overscroll-behavior:contain; flex:1;
  padding-bottom:calc(var(--space-md) + env(safe-area-inset-bottom));}

/* ---------- settings sheet — right edge, both breakpoints ---------- */
.sheet{
  position:fixed; inset:0 0 0 auto; z-index:50;
  width:min(88%,var(--sheet-w)); display:flex; flex-direction:column;
  background:var(--color-paper-2);
  border-left:var(--rule-hair) solid var(--color-rule);
  transform:translateX(0); transition:transform var(--dur-mid) var(--ease-out);
}
.sheet[hidden]{
  display:flex; transform:translateX(101%); pointer-events:none;
  visibility:hidden; transition:transform var(--dur-mid) var(--ease-in),
                                visibility 0s linear var(--dur-mid);
}
.sheet-scroll{overflow-y:auto; overscroll-behavior:contain; flex:1;
  padding:var(--space-sm) var(--space-sm)
          calc(var(--space-lg) + env(safe-area-inset-bottom));}

.scrim{position:fixed; inset:0; z-index:45; background:var(--color-veil);
  opacity:1; transition:opacity var(--dur-mid) var(--ease-out);}
.scrim[hidden]{display:block; opacity:0; pointer-events:none;}

/* ---------- bottom tabbar — thumb zone, mobile + tablet only ---------- */
.tabbar{
  position:fixed; inset:auto 0 0 0; z-index:30; display:flex;
  padding-bottom:env(safe-area-inset-bottom);
  background:var(--color-bar); border-top:var(--rule-hair) solid var(--color-rule);
  -webkit-backdrop-filter:blur(14px) saturate(180%); backdrop-filter:blur(14px) saturate(180%);
}

/* ================= tablet: 640px+ — cards go two-up, rail widens ========= */
@media (min-width:640px){
  .content{padding-inline:var(--space-md);}
  .rail,.sheet{width:min(64%,var(--sheet-w));}
}

/* ================= desktop: 1024px+ — permanent rail, no tabbar ========= */
@media (min-width:1024px){
  .topbar{left:var(--rail-w); padding-inline:var(--space-md);}
  /* A search field the full width of a 1440px viewport reads as a mistake, and
     the caret ends up far from the results. Cap it and let the bar hold the gap. */
  .topbar .search{flex:0 1 30rem; margin-right:auto;}
  .shell{padding-left:var(--rail-w); padding-bottom:0;}
  .content{padding:var(--space-lg) var(--space-lg) var(--space-2xl);}

  /* rail stops being a drawer: always open, in flow, no scrim, no transform */
  .rail{width:var(--rail-w); transform:none; transition:none; z-index:20;}
  .rail[hidden]{
    transform:none; pointer-events:auto; visibility:visible; transition:none;
  }
  .tabbar{display:none;}

  /* the drawer's own close button + the topbar's menu button are mobile-only */
  /* .rail prefix is load-order defence: components.css comes after this file
     and sets .icon-btn{display:grid}, which ties on specificity and would win. */
  .rail .rail-close,.topbar .menu-btn{display:none;}

  /* The rail header sits beside the topbar on PC, so their bottom rules must be
     one continuous line. Pin it to the bar height and shrink the two-line
     wordmark to fit instead of letting it dictate a taller box. */
  .rail .rail-head{
    height:var(--bar-h); padding-block:0; align-items:center;
  }
  .rail .wordmark{font-size:var(--text-md); line-height:1.15;}
  .rail .wordmark span{font-size:var(--text-2xs); margin-top:1px;}
}

/* wide desktop — cap the reading column, keep the rail flush left */
@media (min-width:1440px){
  .content{max-width:1180px;}
}
