/* ══════════════════════════════════════════════════════════════════════════
   app-shell.css — the navigation rail, the page header and the surface grid
   shared by /, /workspace and /dashboard.

   Why this file exists
   ───────────────────
   Polaris had three navigation systems for three surfaces. `/` had none at
   all (its only route to the rest of the product was a dropdown under the
   avatar, which does not exist when you are signed out). /workspace and
   /dashboard each carried their OWN copy of a three-pill row — markup and
   CSS, duplicated — and the two copies had already drifted: they sat at
   different heights, the back button was in the header on one and on its own
   row on the other, and the pill that leads to /dashboard said "Account"
   while the dropdown that leads to the same page said "Dashboard".

   design-tokens.css is 312 variables of tokens and resets with no component
   layer, so every page also rebuilt its own header, its own cards and its own
   tags. This file is that missing layer for the app chrome. It owns NO page
   content: what a surface renders inside .shell-main is still the surface's
   business.

   Rail, not sidebar
   ─────────────────
   Colour comes from --shell-rail* in design-tokens.css, which is deep in BOTH
   themes. That is the one deliberate departure from "follow the palette": the
   rail is chrome and needs to read as a fixed edge the content scrolls
   against. A cream rail on a cream canvas is not an edge.

   Everything here is written in logical properties (inset-inline-*,
   margin-inline-*, padding-inline-*) because half this product's readers are
   in RTL, and a rail that flips to the wrong side is worse than no rail.
   ══════════════════════════════════════════════════════════════════════════ */

/* The page's own centring wrapper becomes a pass-through once the shell is
   mounted inside it. Two layout owners is how you get a 1200px column with a
   238px rail parked on top of its first 238 pixels. */
body.has-shell .wrap{ max-width:none; margin:0; padding:0; }

/* display:flex/grid on a component beats the UA's [hidden] rule, so every
   element in here that is shown conditionally needs the guard named. The
   scope line and the profile block both ship hidden and are filled in later;
   without this they render as an empty bordered box and a nameless avatar. */
.shell-rail [hidden], .shell-head [hidden]{ display:none !important; }

/* The rail's width is a LAYOUT constant, not a palette colour — it lived in
   the token file beside the rail's hexes and went with them when those moved
   into the generated block. It belongs here, with the thing it sizes. */
:root{ --shell-w: 238px; }

/* ── Skip link ─────────────────────────────────────────────────────────── */
.shell-skip{
  position:fixed; inset-block-start:-80px; inset-inline-start:1rem; z-index:200;
  background:var(--panel); color:var(--ink); padding:0.75rem 1rem;
  border:1px solid var(--line); border-radius:0.5rem; text-decoration:none;
}
.shell-skip:focus{ inset-block-start:0.625rem; }

/* ── The rail ──────────────────────────────────────────────────────────── */
.shell-rail{
  position:fixed; inset-block:0; inset-inline-start:0; z-index:50;
  width:var(--shell-w,238px);
  display:flex; flex-direction:column; overflow-y:auto; overscroll-behavior:contain;
  padding:1.5rem 0.875rem 1rem;
  background:linear-gradient(165deg,var(--shell-rail-2),var(--shell-rail) 68%);
  color:var(--shell-rail-ink);
  border-inline-end:1px solid var(--shell-rail-line);
}
.shell-rail a{ text-decoration:none; color:inherit; }

.shell-logo{
  display:flex; align-items:center; gap:0.625rem;
  margin:0 0.5rem 1.375rem; padding:0.25rem;
  font-size:var(--fs-xl); font-weight:700; letter-spacing:-.02em;
  color:var(--shell-rail-ink); border-radius:0.625rem;
}
.shell-logo .shell-logo-mark{
  width:32px; height:32px; flex:none; display:grid; place-items:center;
  border-radius:0.5rem; background:var(--c-accent); color:var(--c-on-accent);
}
.shell-logo .shell-logo-mark .ic{ width:18px; height:18px; }
.shell-logo:focus-visible{ outline:2px solid var(--c-accent); outline-offset:3px; }

/* The workspace/brand line. It is a plain block until a surface puts a real
   control in it, so the rail never shows an empty affordance. */
.shell-scope{
  display:flex; align-items:center; gap:0.5rem;
  margin:0 0.125rem 0.75rem; padding:0.625rem 0.75rem;
  border:1px solid var(--shell-rail-line); background:var(--shell-rail-hover);
  border-radius:0.625rem; font-size:var(--fs-sm); color:var(--shell-rail-ink);
  min-height:44px;
}
.shell-scope .ic{ flex:none; opacity:.75; }
.shell-scope-name{ flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

.shell-cta{
  display:flex; align-items:center; justify-content:center; gap:0.5rem;
  width:calc(100% - 0.25rem); margin:0 0.125rem 1.25rem; min-height:44px;
  padding:0.625rem 1rem; border:0; border-radius:0.625rem;
  background:var(--c-accent); color:var(--c-on-accent);
  font:inherit; font-size:var(--fs-sm); font-weight:700; text-decoration:none;
  box-shadow:0 3px 10px rgba(0,0,0,.18);
}
.shell-cta:hover{ background:var(--c-accent-deep); }

.shell-group{ margin-bottom:1.125rem; }
.shell-group-label{
  margin:0.625rem 0.75rem 0.375rem; font-size:var(--fs-micro); font-weight:700;
  letter-spacing:var(--tracking-label); text-transform:uppercase;
  color:var(--shell-rail-ink-2);
}
.shell-item{
  display:flex; align-items:center; gap:0.75rem; width:100%;
  min-height:44px; margin:0.1875rem 0; padding:0.625rem 0.75rem;
  border:1px solid transparent; border-radius:0.625rem;
  background:transparent; color:var(--shell-rail-ink);
  font:inherit; font-size:var(--fs-sm); text-align:start; cursor:pointer;
}
.shell-item .ic{ flex:none; opacity:.85; }
.shell-item-label{ flex:1; min-width:0; }
.shell-item:hover{ background:var(--shell-rail-hover); }
.shell-item[aria-current]{
  background:linear-gradient(100deg,var(--c-accent-soft),transparent);
  border-color:var(--shell-rail-line);
  box-shadow:inset 3px 0 0 var(--c-accent);
  font-weight:650;
}
/* The active marker is an inset edge, so in RTL it has to move to the other
   edge or it marks the wrong side of the item. */
[dir="rtl"] .shell-item[aria-current]{ box-shadow:inset -3px 0 0 var(--c-accent); }

/* A count that has to be readable without opening anything. */
.shell-badge{
  flex:none; min-width:20px; padding:0.0625rem 0.375rem; border-radius:999px;
  background:var(--c-accent); color:var(--c-on-accent);
  font-size:var(--fs-micro); font-weight:700; text-align:center;
}

.shell-spacer{ flex:1; min-height:1rem; }

.shell-profile{
  display:flex; align-items:center; gap:0.625rem;
  margin-top:0.75rem; padding:0.875rem 0.5rem 0;
  border-top:1px solid var(--shell-rail-line);
  font-size:var(--fs-xs); color:var(--shell-rail-ink);
}
.shell-profile-id{ flex:1; min-width:0; }
.shell-profile-id b{ display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.shell-profile-id small{ color:var(--shell-rail-ink-2); }

.shell-avatar{
  width:34px; height:34px; flex:none; border-radius:50%;
  display:inline-grid; place-items:center;
  background:var(--c-accent); color:var(--c-on-accent);
  font-size:var(--fs-xs); font-weight:700;
}

/* ── The canvas ────────────────────────────────────────────────────────── */
.shell-body{ margin-inline-start:var(--shell-w,238px); max-width:1900px; }

.shell-head{
  display:flex; align-items:center; gap:1rem;
  padding:1.5rem 2rem 1.125rem;
  /* ⛔ Between the phone breakpoint and a wide desktop the rail still takes
     210px and the actions (bell, language, address, sign out, theme) never
     wrapped, so the title column was squeezed to one word per line — at 762px
     the H1 measured 16px wide and "What you are working on" read down the
     page. Seen on the founder's signed-in session 2026-09-15. The title now
     claims a real width first, and the actions drop to a second row when
     both do not fit; on a wide screen nothing moves. */
  flex-wrap:wrap;
}
.shell-head-title{ flex:1 1 18rem; min-width:0; }
.shell-head-title h1{ margin:0; font-size:var(--fs-2xl); font-weight:700; letter-spacing:-.02em; line-height:var(--lh-tight); }
.shell-head-title p{ margin:0.375rem 0 0; font-size:var(--fs-sm); color:var(--ink-3); }
/* position:relative so a control in here can hang a panel off itself — the
   workspace's notification popover is anchored to this box, not to the page.
   Before the shell it happened to line up because the bell WAS at the page's
   right edge; once the header owned the bell, a panel pinned to the page edge
   floated away from the button that opened it. */
.shell-head-actions{ display:flex; align-items:center; gap:0.5rem; position:relative; flex-wrap:wrap; }

.shell-icon-btn{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:44px; min-height:44px; padding:0.5rem;
  border:1px solid transparent; border-radius:0.625rem;
  background:transparent; color:var(--ink-2); font:inherit; cursor:pointer;
  position:relative;
}
.shell-icon-btn:hover{ background:var(--panel-2); color:var(--ink); }
.shell-count{
  position:absolute; inset-block-start:4px; inset-inline-end:4px;
  min-width:18px; padding:0 4px; border-radius:999px;
  background:var(--c-err); color:#fff; font-size:var(--fs-micro); font-weight:700; line-height:18px;
}

.shell-main{ padding:0 2rem 2rem; }
.shell-foot{
  display:flex; flex-wrap:wrap; gap:0.75rem; justify-content:space-between;
  padding:0.75rem 2rem 1.75rem; font-size:var(--fs-xs); color:var(--ink-3);
}
.shell-foot a{ color:var(--ink-3); }

/* ── Mobile drawer ─────────────────────────────────────────────────────── */
.shell-scrim{
  position:fixed; inset:0; z-index:40; border:0; border-radius:0; padding:0;
  background:rgba(20,14,8,.55); cursor:pointer;
}
.shell-menu-btn{ display:none; }

@media (max-width:1200px){
  .shell-rail{ width:210px; padding-inline:0.625rem; }
  .shell-body{ margin-inline-start:210px; }
  .shell-head{ padding:1.25rem 1.5rem 1rem; }
  .shell-main{ padding:0 1.5rem 1.5rem; }
  .shell-foot{ padding:0.75rem 1.5rem 1.5rem; }
}

@media (max-width:760px){
  .shell-rail{
    width:min(280px,84vw);
    transform:translateX(-105%);
    transition:transform .22s var(--ease,ease);
  }
  [dir="rtl"] .shell-rail{ transform:translateX(105%); }
  .shell-rail.is-open{ transform:translateX(0); }
  .shell-body{ margin-inline-start:0; }
  .shell-menu-btn{ display:inline-flex; }
  .shell-head{ padding:1rem; gap:0.5rem; flex-wrap:wrap; }
  .shell-head-title p{ display:none; }
  .shell-head-title h1{ font-size:var(--fs-xl); overflow-wrap:anywhere; }
  /* The header carries the menu button, the title, a bell, a three-way
     language switch, a theme toggle and a who-am-I chip. On a 390px phone
     that is wider than the screen, and a header that overflows scrolls the
     whole page sideways — which also drags the FIXED drawer out of view, so
     opening the menu appeared to show half a rail. Two rows instead. */
  .shell-head-actions{ flex:1 1 100%; order:3; justify-content:flex-start; flex-wrap:wrap; }
  /* The address is the widest thing in the row and the least useful there:
     the rail already says who is signed in. */
  .shell-head-actions .who b{ display:none; }
  .shell-main{ padding:0 1rem 1.5rem; }
  .shell-foot{ padding:0.75rem 1rem 1.5rem; flex-direction:column; }
}

/* A drawer over a page that still scrolls behind it loses the reader's place. */
body.shell-drawer-open{ overflow:hidden; }

/* The drawer animation is the one thing here that moves; honour the global
   reduced-motion preference explicitly because the transform is inline to
   this component. */
@media (prefers-reduced-motion: reduce){
  .shell-rail{ transition:none; }
}
