/* ═══════════════════════════════════════════════════════════
   4. LEFT ICON RAIL + MAIN PANEL  (combined single page)
   The icons on the left each toggle one view of a panel that covers the
   viewport, minus the rail. Re-pressing the active icon closes it, and the
   « at the top of the rail hides the rail itself — see "Hiding the rail".
   ═══════════════════════════════════════════════════════════ */

:root {
  /* The rail's own width, and the width it costs the layout. They are the
     same until the rail is hidden, when --rail-w drops to 0 and the panel,
     the landing page and the footer all reclaim the space on their own —
     that one variable is the whole hide/show mechanism. */
  --rail-w-base: 60px;
  --rail-w: var(--rail-w-base);

  /* Content widths inside the panel. It is as wide as the viewport now, so
     nothing may take that width just because it can — see "Content widths"
     below. All three are max-widths, so a phone never sees them. */
  --w-col:  1400px;     /* the centred column everything lives in */
  --w-form: 66rem;      /* forms and single controls */
  --w-read: 120ch;      /* prose, and cards that come one per row */
  --panel-pad-x: clamp(16px, 3vw, 44px);
}

/* keep landing content clear of the fixed rail */
main   { padding-left: calc(2rem + var(--rail-w)); }
footer { padding-left: calc(var(--rail-w) + 1rem); padding-right: 1rem; }

/* ─── Icon rail ─────────────────────────────────────────── */
.rail {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  /* --rail-w-base, not --rail-w: hiding the rail zeroes the latter, and a
     rail collapsed to 0px would spill its buttons instead of sliding out. */
  width: var(--rail-w-base);
  z-index: 200;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 16px 0;
  background: rgba(13, 8, 2, 0.6);
  border-right: 1px solid var(--gold-dim);
  backdrop-filter: blur(2px);
  /* visibility, not just transform: an off-screen rail that is merely
     translated stays in the tab order, so a keyboard user would tab into
     buttons nobody can see. It flips only once the slide has finished. */
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), visibility 0s;
}

/* ─── Hiding the rail ───────────────────────────────────── */
/* The class sits on <html>, not <body>, so the inline script in <head> can
   restore a hidden rail before the first paint — on <body> the rail would
   render and then visibly slide away on every page load. */
/* Not 0: the » tab keeps a lane of its own, so it sits beside the panel
   instead of floating over its heading — which at a phone's 16px gutter
   lands right on top of the title. 26px still buys back most of the rail. */
:root.rail-hidden { --rail-w: 26px; }
:root.rail-hidden .rail {
  transform: translateX(-100%);
  visibility: hidden;
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), visibility 0s linear 0.3s;
}

/* The « button at the top of the rail, and the » tab that replaces it.
   Both are always in the DOM; only one is ever visible. */
.rail-toggle {
  flex: 0 0 auto;
  width: 34px;
  height: 28px;
  margin-bottom: 4px;
  display: grid;
  place-items: center;
  position: relative;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  color: var(--gold-dim);
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.rail-toggle svg { width: 18px; height: 18px; }
.rail-toggle:hover { color: var(--gold); border-color: var(--gold-dim); background: rgba(212, 160, 23, 0.1); }
.rail-toggle:hover .rail-label,
.rail-toggle:focus-visible .rail-label { opacity: 1; }

.rail-show {
  position: fixed;
  top: 12px;
  left: 0;
  z-index: 205;
  width: 26px;
  height: 38px;
  display: grid;
  place-items: center;
  border: 1px solid var(--gold-dim);
  border-left: none;
  border-radius: 0 8px 8px 0;
  background: rgba(13, 8, 2, 0.9);
  color: var(--gold);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateX(-100%);
  transition: opacity 0.25s, transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
              background 0.2s, visibility 0s linear 0.3s;
}
.rail-show svg { width: 16px; height: 16px; }
.rail-show:hover { background: rgba(212, 160, 23, 0.16); }
:root.rail-hidden .rail-show {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateX(0);
  transition: opacity 0.25s, transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
              background 0.2s, visibility 0s;
}

/* "About me" sits at the bottom of the rail — secondary to the site's main views.
   The auto top-margin absorbs the free space, pushing this button to the bottom
   and packing the others at the top. */
.rail-btn--bottom { margin-top: auto; }

.rail-btn {
  position: relative;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 10px;
  border: 1px solid var(--gold-dim);
  background: rgba(26, 16, 5, 0.5);
  color: var(--gold);
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s, background 0.2s, box-shadow 0.2s, transform 0.12s;
}
.rail-btn svg { width: 22px; height: 22px; }
.rail-btn:hover { border-color: var(--gold); background: rgba(212, 160, 23, 0.12); }
.rail-btn:active { transform: scale(0.94); }
.rail-btn[aria-pressed="true"] {
  color: var(--gold-lt);
  border-color: var(--gold);
  background: rgba(212, 160, 23, 0.18);
  box-shadow: 0 0 16px rgba(212, 160, 23, 0.35), inset 0 0 0 1px var(--gold-dim);
}

/* hover flyout label */
.rail-label {
  position: absolute;
  left: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%);
  white-space: nowrap;
  font-family: var(--sans);
  font-size: 0.65rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text);
  background: rgba(13, 8, 2, 0.95);
  border: 1px solid var(--gold-dim);
  border-radius: 4px;
  padding: 5px 9px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
  z-index: 210;
}
.rail-btn:hover .rail-label,
.rail-btn:focus-visible .rail-label { opacity: 1; }

/* ─── Main panel (the whole viewport, minus the rail) ───── */
.sidebar {
  position: fixed;
  top: 0;
  bottom: 0;
  left: var(--rail-w);
  /* Desktop and mobile alike: there is nothing worth showing beside the
     panel, so it takes everything the rail leaves. Content inside is held
     to readable widths instead — see "Content widths". */
  width: calc(100vw - var(--rail-w));
  z-index: 150;
  /* Opaque. At 420px wide the old 0.97 read as depth; covering the whole
     viewport it just lets the landing headline ghost through the panel. */
  background-color: rgb(13, 8, 2);
  background-image:
    linear-gradient(var(--circuit) 1px, transparent 1px),
    linear-gradient(90deg, var(--circuit) 1px, transparent 1px);
  background-size: 48px 48px;
  border-right: 1px solid var(--gold-dim);
  box-shadow: 12px 0 40px rgba(0, 0, 0, 0.55);

  /* hidden fully off-screen to the left (behind the rail) */
  transform: translateX(calc(-100% - var(--rail-w)));
  visibility: hidden;
  /* left/width ride the rail's 0.3s so hiding it slides the panel open
     rather than snapping it. */
  transition: transform 0.42s cubic-bezier(0.4, 0, 0.2, 1),
              left 0.3s cubic-bezier(0.4, 0, 0.2, 1),
              width 0.3s cubic-bezier(0.4, 0, 0.2, 1),
              visibility 0s linear 0.42s;
  will-change: transform;
}
.sidebar.open {
  transform: translateX(0);
  visibility: visible;
  transition: transform 0.42s cubic-bezier(0.4, 0, 0.2, 1),
              left 0.3s cubic-bezier(0.4, 0, 0.2, 1),
              width 0.3s cubic-bezier(0.4, 0, 0.2, 1),
              visibility 0s;
}

/* The panel spans the viewport, but its contents do not sprawl across it:
   they sit in one centred column, and everything inside that column is
   left-aligned to the same edge. Under --w-col — every phone, and a laptop
   once the rail is counted — this is a no-op and the column is the panel. */
.panel-inner {
  height: 100%;
  max-width: var(--w-col);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  padding: 22px var(--panel-pad-x) 18px;
  overflow: hidden;
}

.panel-view {
  height: 100%;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.panel-view[hidden] { display: none; }

/* ═══════════════ Content widths ═══════════════════════════
   The panel is as wide as the viewport, so the job here is to stop things
   taking that width merely because they can. Three classes of content:

     • forms and single controls   → --w-form, left-aligned
     • prose, and cards that come one per row → --w-read
     • grids and chip clouds       → the whole width; that is the point

   Every rule below is a max-width, so on a phone — where the panel was
   always full width and these blocks were always narrower than the cap —
   nothing changes. Nothing needs a margin to sit left: a block box with a
   max-width already starts at the left edge, and a flex child stretches to
   the cap. Do not add `margin-right: auto` here — an auto cross-axis margin
   cancels `align-items: stretch`, and the capped block silently collapses
   to the width of its own text.
   ═══════════════════════════════════════════════════════ */

/* Forms and controls. */
.places-filters,
.places-refine,
.geo-coords,
.geo-radius,
.geo-nearby-filter,
.geo-nearby-pager,
.browse-pager,
.news-pager,
.bf-title,
.bf-toggle,
.car-form,
.movie-history-field,
.quiz-games,
.quiz-choices,
.quiz-progress,
.quiz-missed-list {
  max-width: var(--w-form);
}
/* Two short buttons shouldn't split a 34rem row between them. */
.pf-actions { max-width: 39rem; }
/* Both are `justify-content: space-between` rows, so a wide one strands its
   value half a screen from its label. */
.geo-coords,
.geo-radius { max-width: 39rem; }

/* Prose, and the card streams that come one per row: a line of text 200
   characters wide is unreadable however much room there is for it. */
.chat,
.composer,
.movie-intro,
.movie-card,
.movie-status,
.geo-status,
.geo-place,
.geo-attribution,
.places-hint,
.places-status,
.news-status,
.news-empty,
.news-item,
.browse-status,
.browse-empty,
.car-card,
.car-demo-note,
.car-disclaimer,
.quiz-status,
.quiz-intro,
.quiz-meta,
.quiz-qnum,
.quiz-word,
.quiz-verdict,
.quiz-result-title,
.quiz-score,
.quiz-feedback,
.quiz-missed,
.quiz-make,
.quiz-typed {
  max-width: var(--w-read);
}

/* Left uncapped on purpose: .bm-grid (auto-fill columns — more of them is
   the whole gain), .geo-nearby-list (a wrapping chip cloud), .bf-groups,
   .news-tabs and .movie-level (content-sized already), and every scroll
   container, which must stay full width for its children to be capped
   against something stable. */

.panel-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-bottom: 14px;
  margin-bottom: 8px;
  border-bottom: 1px dashed rgba(139, 105, 20, 0.3);
}
.panel-avatar {
  width: 92px;
  height: 92px;
  flex: 0 0 auto;
  border-radius: 50%;
  overflow: hidden;
  border: 1px solid var(--gold);
  background: var(--parchment);
}
.panel-avatar img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: sepia(0.3) contrast(1.1);
}
.panel-title {
  font-family: "Cinzel Decorative", serif;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--gold);
  letter-spacing: 0.03em;
  line-height: 1.2;
  text-shadow: 0 0 24px rgba(212, 160, 23, 0.3);
}


/* ─── Scrim (mobile only) ───────────────────────────────── */
.scrim {
  position: fixed;
  inset: 0;
  z-index: 140;
  background: rgba(0, 0, 0, 0.55);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s, visibility 0s linear 0.3s;
}

/* ─── Mobile ────────────────────────────────────────────── */
@media (max-width: 900px) {
  /* Only the rail narrows. The panel was already viewport-wide here, and
     now the desktop rule says the same thing, so it needs no override. */
  :root { --rail-w-base: 54px; }
  body.panel-open { overflow: hidden; }
  body.panel-open .scrim {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.3s;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar { transition: visibility 0s; }
  .rail, .rail-show { transition: none; }
}
