/* ── Foundations — injected :root/dark tokens, theme transition, body, focus, #page-container ─── */

:root{
  --bb-color-mode: 99;
  --bs-body-bg: #f9f9f9;
  --my-background: #f9f9f9;
  --bs-body-color: #222;
  --my-white: #fff;
  --my-white-rgb: 255, 255, 255;
  --my-black: #111;
  --my-silver-1: #ddd;
  --my-silver-2: #f5f5f5;
  --my-gray-1: #777;
  --my-gray-2: #555;
  --my-gray-3: #333;
  --my-border-color: #22222222;
  --my-shadow-color: #11111133;
  --my-theme-accent: #0047AB;
  --my-theme-night: #7EB2FF;
  --my-theme-day: #FCA61C;
  --my-error: #c0392b;
  --my-overlay-scrim: #00000073;
  --my-font-title: "Spectral", serif;
  --my-font-subtitle: "Instrument Serif", serif;
  --my-font-subtitle-alt: "Edu SA Beginner", cursive;
  --my-font-article: "Slabo 27px", serif;
  --my-font-article-alt: "Quicksand", sans-serif;
  --my-font-ui: "Montserrat", sans-serif;
  --my-font-code: "Inconsolata", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --my-font-hero: var(--my-font-title);
  --my-font-nav: var(--my-font-title);
  --my-font-button: var(--my-font-ui);
  --my-font-date: var(--my-font-ui);
  --my-font-form: var(--my-font-ui);
  --my-font-lede: var(--my-font-subtitle-alt);
  --my-font-caption: var(--my-font-ui);
  --radius-md: 12px;
  --radius-pill: 999px;
  --radius-sm: 4px;
  --nav-height: calc(4.5rem + env(safe-area-inset-bottom));
  --motion-base: 200ms;
  --motion-fast: 120ms;
  --motion-loader: 1.2s;
  --motion-slow: 350ms;
  --z-critical: 9000;
  --z-fixed: 10;
  --z-hints: 1500;
  --z-overlay: 1400;
  --z-pill: 8;
  --z-rail: 1;
  --z-toast: 1501;
  --shadow-sm: 0 0 8px 0 var(--my-shadow-color);
  --shadow-md: 0 0 10px 0 var(--my-shadow-color);
  --shadow-lg: 0 12px 48px var(--my-shadow-color);
  --shadow-panel: var(--my-border-color) 0px 3px 6px;
  --glow-sm: var(--my-theme-accent) 0 0 1px;
  --glow-md: var(--my-theme-accent) 0 0 4px;
  --glow-lg: var(--my-theme-accent) 0 0 8px;
}

html[data-bs-theme="dark"] {
  --bb-color-mode: 00;
  --bs-body-bg: #181818;
  --my-background: #181818;
  --bs-body-color: #fbfbfb;
  --my-white: #111;
  --my-white-rgb: 17, 17, 17;
  --my-black: #fff;
  --my-silver-1: #2d2d2d;
  --my-silver-2: #222;
  --my-gray-1: #ccc;
  --my-gray-2: #bbb;
  --my-gray-3: #aaa;
  --my-border-color: #fbfbfb22;
  --my-shadow-color: #fdfdfd33;
  --my-theme-accent: #6B9EFF;
  --my-theme-night: #7EB2FF;
  --my-theme-day: #FCA61C;
  --my-error: #e85d50;
  --my-overlay-scrim: #00000073;
}

html.theme-transitioning *,
html.theme-transitioning *::before,
html.theme-transitioning *::after {
  transition: background-color var(--motion-base) ease-in, color var(--motion-fast) ease-out;
}


html[data-bs-theme="dark"]  .theme-img--light { display: none; }
html[data-bs-theme="light"] .theme-img--dark  { display: none; }

body {
  --signature-height:80px;
  --signature-bg-duration:0.25s;
  --signature-stroke-duration:0.5s;
  /* Frosted-panel corner radius — derived from the signature footprint so the
     whole command-console family rounds consistently. */
  --panel-radius: calc(var(--signature-height) * 0.4);
  font-family: var(--my-font-ui);
  max-width:100vw;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  scrollbar-gutter: stable both-edges;
}

.top-spacer{
  height: 10vh;
  transition-property: height;
  transition-duration: var(--motion-base);
  transition-timing-function: ease-in-out;
}

.top-spacer.contract{
  height: 0;
}

#command-console-tray.hide,
#navigation-panel.hide,
#action-panel.hide,
#pg-toc-panel.hide { display: none; }

:focus-visible {
  outline: 2px solid var(--my-theme-accent);
  outline-offset: 2px;
  border-radius: 2px; /* softens corners on rectangular controls */
}
.corner-picker__dot:focus-visible,
#command-console:focus-visible {
  outline: none;
}

#page-container {
  width:100%;
  height:100vh;
  display: flex;
  flex-direction: column;
  background-color: var(--my-background);
  color: var(--bs-body-color);
  overflow-x: clip; /* clip, not hidden — avoids creating a scroll container */
}

/* ── Command console — corner positioning, drag, focus + signature pill & SVG letters ─── */

#command-console{
  position: fixed;
  display: flex;
  justify-content: end;
  z-index: var(--z-fixed);
  height:auto;
  cursor: grab;

  touch-action: none;
  transition: transform var(--motion-slow) cubic-bezier(0.32, 0.72, 0, 1);
}

#command-console.left{
 left:2.5vw;
 align-items: start;
}

#command-console.right{
 right:2.5vw;
 align-items: end;
}

#command-console.top{
  flex-direction: column;
 top:2.5vw;
}

#command-console.bottom{
  flex-direction: column-reverse;
 bottom:calc(2.5vw + 4.5vh);
}

#command-console.dragging {
  transition: none;
  cursor: grabbing;
}

#theme-toggle:active,
#shortcuts-toggle:active {
  transform: scale(0.96);
}

.corner-picker__dot:active {
  transform: scale(0.88);
}

#command-console:focus{
  outline: none;
}

#command-console:focus-visible #signature-panel {
  box-shadow:
    var(--shadow-panel),
    0 0 8px 1px color-mix(in srgb, var(--my-theme-accent) 10%, transparent);
}

#signature-panel{
  overflow: hidden;
  width: var(--signature-height);
  border-radius: var(--panel-radius);
  background-color: rgba(var(--my-white-rgb), 0.8);
  box-shadow: var(--shadow-panel);
  padding: calc(var(--signature-height)/4);
  padding-bottom: calc(var(--signature-height)/5.5);
  opacity:0;
  animation: fadeIn 1.75s ease-in-out forwards;
  animation-delay: 0s;
  z-index: var(--z-pill);
  backdrop-filter: blur(20px);
  transition: width var(--signature-bg-duration) ease;
  transition-duration: var(--motion-slow);
  transition-delay: calc(var(--signature-stroke-duration)*0.68);
  -webkit-backdrop-filter: blur(20px);
}

#command-console:focus #signature-panel{
  outline: none;
  width: calc(2*var(--signature-height));
  transition-delay: 0s;
}

#signature{
  left: calc(var(--signature-height)/11);
  position: relative;
  height: calc(var(--signature-height)*0.568);
}


.signature-letters {
  fill: none;
  stroke: var(--my-black);
  stroke-width: 100px;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-miterlimit: 1.5;
  stroke-dasharray: none;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset var(--signature-stroke-duration) ease-out;
}

#command-console:focus .signature-letters{
  stroke-dashoffset: 0;
  transition-duration: var(--motion-base);
}

#NameR1{
  animation: writeStroke 2s ease forwards;
  animation-delay: 0.5s;
}

#NameA{transition-delay: 0.25s; transition-duration: var(--motion-base);}
#command-console:focus #NameA{transition-delay: 0s; transition-duration: var(--motion-fast);}

#NameJ{transition-delay: 0.20s; transition-duration: var(--motion-base);}
#command-console:focus #NameJ{transition-delay: 0.05s; transition-duration: var(--motion-base);}

#NameJdot{transition-delay: 0.20s; transition-duration: var(--motion-base);}
#command-console:focus #NameJdot{transition-delay: 0.05s; transition-duration: var(--motion-base);}

#NameN{transition-delay: 0.15s; transition-duration: var(--motion-base);}
#command-console:focus #NameN{transition-delay: 0.10s; transition-duration: var(--motion-base);}

#NameO1{transition-delay: 0.10s; transition-duration: var(--motion-base);}
#command-console:focus #NameO1{transition-delay: 0.15s; transition-duration: var(--motion-base);}

#NameO2{transition-delay: 0.05s; transition-duration: var(--motion-base);}
#command-console:focus #NameO2{transition-delay: 0.20s; transition-duration: var(--motion-base);}

#NameR2{transition-delay: 0.0s; transition-duration: var(--motion-fast);}
#command-console:focus #NameR2{transition-delay: 0.25s; transition-duration: var(--motion-base);}

/* ── Command panels — tray, .command-panel surface, navigation + action panels ─── */

#command-console-tray{
  display:flex;
  position: relative;
  left: 0;
  padding: 0 !important;
  margin-block: calc(0.25*var(--signature-height));

  background-color: transparent;
  box-shadow: none;

  --navItemHeightFactor:0.6;
}

.top #command-console-tray{
  flex-direction: column;
}

.bottom #command-console-tray{
  flex-direction: column-reverse;
}

/* Shared frosted surface for the expanding command-console panels
   (#navigation-panel + #action-panel). Parallel to .page-panel on the
   page-console; the resting #signature-panel keeps its own surface inline so
   the per-corner transform-origin rules below don't bleed onto it. */
.command-panel{
  border-radius: var(--panel-radius);
  background-color: rgba(var(--my-white-rgb), 0.8);
  box-shadow: var(--shadow-panel);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}

#command-console.top.left    .command-panel { transform-origin: top left; }
#command-console.top.right   .command-panel { transform-origin: top right; }
#command-console.bottom.left  .command-panel { transform-origin: bottom left; }
#command-console.bottom.right .command-panel { transform-origin: bottom right; }

#navigation-panel{
  --y-offset: calc(0.15 * var(--signature-height));
  overflow: hidden;
  position: relative;
  display: flex;
  width: calc(2 * var(--signature-height));

  flex-direction: column;
  align-items: center;
  justify-content: start;

  padding: calc(0.15*var(--signature-height)) calc(0.2*var(--signature-height));

  animation-name: none;
  /* Injected from the same source the JS cleanup reads (data/script.yaml ›
     console) so the CSS animation and the JS teardown timer can't drift. */
  animation-duration: 180ms;
  animation-timing-function: ease-out;
  animation-fill-mode: both;
}

#navigation-panel::before,
#navigation-panel::after {
  content: "";
  position: absolute;
  left : 0px;
  height: calc(0.3 * var(--signature-height));
  background: var(--my-black);
  border-radius: 2px;
  pointer-events: none;
  transition: top var(--motion-slow) cubic-bezier(0.22, 1, 0.36, 1), opacity var(--motion-fast) ease;
}
#navigation-panel::before {
  top: calc(var(--active-y, 0px) + var(--y-offset));
  width: 2px;
  opacity: var(--active-shown, 0);
  z-index: calc(var(--z-rail) + 1);
}
#navigation-panel::after {
  top: calc(var(--hover-y, 0px) + var(--y-offset));
  width: 1px;
  opacity: var(--hover-shown, 0);
  z-index: var(--z-rail);
}

#navigation-panel.show{
  display: flex;
  animation-name: panelExpand;
}

#navigation-panel.contract{
  animation-name: panelCollapse;
}

.nav-item{
  display: flex !important;
  font-family: var(--my-font-title);
  font-size: 1rem;

  width: 100%;
  height: calc(0.6*var(--signature-height));

  align-items: center;
  justify-content: center;
  transition: display calc(var(--signature-bg-duration)/5) ease, color 0s;
}
.nav-link{
  position: relative;
  display: block;
  width: 100%;
  height: 50%;  
  padding-block: 0 !important;
  padding-inline: calc(0.1*var(--signature-height)) !important;
  margin-left: calc(0.1*var(--signature-height));
}
.nav-link__text{
  position: absolute;
  top: 50%;
  left: calc(0.1*var(--signature-height));
  right: calc(0.1*var(--signature-height));
  transform: translateY(-50%);
  line-height: 1;
}

#home-nav{
  transition-delay: calc(var(--signature-bg-duration)/5);
}

#project-nav{
  transition-delay: calc(2*var(--signature-bg-duration)/5);
}

#cred-nav{
  transition-delay: calc(3*var(--signature-bg-duration)/5);
}

#action-panel{
  display: flex;
  position: relative;
  overflow: hidden;
  margin-block: calc(0.25*var(--signature-height));

  flex-direction: row;
  justify-content: space-evenly;
  align-items: center;

  padding: calc(0.1*var(--signature-height)) calc(0.1*var(--signature-height));

  width: calc(2 * var(--signature-height));
  /* See #navigation-panel: injected from data/script.yaml › console. */
  animation-duration: 120ms;
  animation-timing-function: ease-out;
  animation-fill-mode: both;
}

#action-panel.show{
  display: flex;
  animation-name: panelExpand;
}

#action-panel.contract{
  animation-name: panelCollapse;
}

@keyframes panelExpand {
  from { transform: scale(0.7); opacity: 0; }
  to   { transform: scale(1);   opacity: 1; }
}

@keyframes panelCollapse {
  from { transform: scale(1);   opacity: 1; }
  to   { transform: scale(0.7); opacity: 0; }
}

.action-item{
  display: flex !important;
  font-size: 1.15rem;
  justify-content: center;
  align-items: center;
  height: calc(0.45*var(--signature-height));
  width: calc(0.45*var(--signature-height));
  flex: 0 0 calc(0.45*var(--signature-height));
  border: none;
  transition: display calc(var(--signature-bg-duration)/5) ease, color 0s;
}

.action-item.show{
  display: flex !important;
}

#theme-toggle{
  transition: transform var(--motion-slow) ease-in, color 0.02s ease-out 0.05s;
  background-color: transparent !important;
  /* Explicit colour — mobile Safari paints unstyled <button> text in the
     system tint (blue on iOS), which leaks into the Material Symbols glyph. */
  color: var(--bs-body-color);
  border: none;
  padding: 0;
  touch-action: manipulation;
  -webkit-appearance: none;
  -webkit-tap-highlight-color: transparent;
}
#theme-toggle:hover {
  text-shadow: var(--my-theme-day) 0px 0px 4px;
}
html[data-bs-theme="dark"] #theme-toggle:hover {
  text-shadow: var(--my-theme-night) 0px 0px 8px;
}

#corner-picker {
  display: grid !important;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 4px;
  padding: 8px;
  background: transparent !important;
  /* width/height come from .action-item so all three items stay equiwidth */
}

.corner-picker__dot {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  border: 1px solid var(--my-border-color);
  background: transparent;
  padding: 0;
  cursor: pointer;
  transition: background-color var(--motion-base) ease, transform var(--motion-fast) ease, border-color var(--motion-base) ease;
}

.corner-picker__dot:hover,
.corner-picker__dot:focus-visible {
  transform: scale(1.25);
  outline: none;
  border-color: var(--my-black);
}

.corner-picker__dot.active {
  background-color: var(--my-black);
  border-color: var(--my-black);
}

/* ── Controls — WCAG touch targets, shortcuts toggle, corner targets, hover-grow ─── */

/* ── Touch target extension (WCAG 2.5.5 — minimum 44×44 px) ───────────────
   The visual size of these controls (~36 px) is intentional, so we don't
   resize them; instead we extend the hit area via an invisible ::before
   pseudo. Pointer-events fall through to the parent button. */
.pg-head__item, .action-item, .corner-picker__dot { position: relative; }
.pg-head__item::before,
.action-item::before,
.corner-picker__dot::before {
  content: "";
  position: absolute;
  inset: -4px;          /* 36 + 4 + 4 = 44 px hit area */
  pointer-events: auto; /* explicit: clicks within the extended area still hit the button */
  background: transparent;
}

#shortcuts-toggle {
  background-color: transparent !important;
  border: none;
  padding: 0;
  font-size: 1.4rem;
  line-height: 1;
  color: var(--bs-body-color);
  touch-action: manipulation;
  transition: text-shadow var(--motion-fast) ease, transform var(--motion-fast) ease;
}
#shortcuts-toggle .material-symbols-rounded {
  font-variation-settings: 'wght' 300;
}
#shortcuts-toggle:hover {
  text-shadow: var(--glow-sm);
}
html[data-bs-theme="dark"] #shortcuts-toggle:hover {
  text-shadow: var(--glow-lg);
}

#corner-targets {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: calc(var(--z-pill) + 1);
  opacity: 0;
  transition: opacity var(--motion-fast) ease;
}

#corner-targets.visible {
  opacity: 1;
}

.corner-target {
  position: absolute;
  width: calc(var(--signature-height) * 0.6);
  height: calc(var(--signature-height) * 0.6);
  border: 2px dashed var(--my-border-color);
  border-radius: var(--panel-radius);
}

.corner-target.TL { top: 2.5vw; left: 2.5vw; }
.corner-target.TR { top: 2.5vw; right: 2.5vw; }
.corner-target.BL { bottom: calc(2.5vw + 4.5vh); left: 2.5vw; }
.corner-target.BR { bottom: calc(2.5vw + 4.5vh); right: 2.5vw; }

.hover-grow {
  display: inline-block;
  transition: transform var(--motion-slow) ease, letter-spacing var(--motion-slow) ease;
}

.hover-grow:hover {
  transform: scale(1.05);
  letter-spacing: 0.05em;
}

button {
  -webkit-tap-highlight-color: transparent;
  outline: none;
}

/* ── Motion — shared keyframes, card + page-content transitions, reduced-motion ─── */

@keyframes writeStroke {
  to {
    stroke-dashoffset: 0;
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes rotateAnim {
  0%   { transform: rotate(0deg);   animation-timing-function: ease-in;  }
  50%  { transform: rotate(180deg); animation-timing-function: ease-out; }
  100% { transform: rotate(360deg); }
}

.rotate {
  display: inline-block;
  animation: rotateAnim 1s;
}

@keyframes iconSwap {
  0%   { opacity: 1; transform: scale(1) rotate(0deg); }
  40%  { opacity: 0; transform: scale(0.7) rotate(90deg); }
  60%  { opacity: 0; transform: scale(0.7) rotate(90deg); }
  100% { opacity: 1; transform: scale(1) rotate(0deg); }
}
.icon-swap {
  animation: iconSwap var(--motion-slow) ease;
}

@keyframes discoverPulse {
  0%   { box-shadow: 0 0 0   0   var(--my-theme-accent); }
  35%  { box-shadow: 0 0 22px 6px var(--my-theme-accent); }
  70%  { box-shadow: 0 0 10px 2px var(--my-theme-accent); }
  100% { box-shadow: 0 0 0   0   transparent; }
}
/* #signature-panel has animation: fadeIn on the ID rule (specificity 1,0,0).
   A plain .discover-pulse class (0,1,0) would lose the cascade and never run.
   Combining ID + class (1,1,0) wins, and listing fadeIn with a negative delay
   equal to its duration instantly completes it — keeping opacity at 1 via
   the forwards fill — while discoverPulse runs freely on box-shadow. */
#signature-panel.discover-pulse {
  animation:
    fadeIn 1.75s ease-in-out -1.75s forwards,
    discoverPulse 2.4s ease-out 1;
}


.card {
  transition: box-shadow var(--motion-base) ease, transform var(--motion-base) ease;
}
.card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

#page-content {
  transition: opacity var(--motion-fast) ease, transform var(--motion-fast) ease;
}
#page-content.page-leaving {
  opacity: 0;
  transform: translateY(6px);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Overlays — spotlight search, scroll arc, shortcuts hints ──────────────────── */

.spotlight-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  background: var(--my-overlay-scrim);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  align-items: flex-start;
  justify-content: center;
  padding-top: 20vh;
}

.spotlight-overlay--open {
  display: flex;
}

.spotlight-overlay__panel {
  background: var(--my-white);
  border: 1px solid var(--my-border-color);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  width: 90vw;
  max-width: 36rem;
  overflow: hidden;
}

.spotlight-overlay__input {
  width: 100%;
  padding: 1rem 1.25rem;
  font-family: var(--my-font-ui);
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--bs-body-color);
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--my-border-color);
  outline: none;
}

.spotlight-overlay__input::placeholder {
  color: var(--my-gray-1);
  font-weight: 400;
}

.spotlight-overlay__list {
  list-style: none;
  margin: 0;
  padding: 0.4rem 0;
  max-height: 22rem;
  overflow-y: auto;
}

.spotlight-overlay__item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.65rem 1.25rem;
  cursor: pointer;
  transition: background-color var(--motion-fast) ease;
}

.spotlight-overlay__item.active,
.spotlight-overlay__item:hover {
  background: var(--my-silver-2);
}

.spotlight-overlay__title {
  font-family: var(--my-font-title);
  font-size: 0.95rem;
  font-weight: 400;
  color: var(--bs-body-color);
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.spotlight-overlay__kind {
  font-family: var(--my-font-ui);
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--my-gray-1);
  background: var(--my-silver-1);
  border-radius: var(--radius-sm);
  padding: 0.1rem 0.4rem;
  white-space: nowrap;
  flex-shrink: 0;
}

.spotlight-overlay__status {
  padding: 0.75rem 1.25rem;
  font-family: var(--my-font-ui);
  font-size: 0.82rem;
  color: var(--my-gray-1);
}

.spotlight-overlay__status--error {
  color: var(--my-error);
}

.spotlight-overlay__retry {
  background: none;
  border: 1px solid currentColor;
  border-radius: var(--radius-pill);
  color: var(--my-error);
  cursor: pointer;
  font-family: var(--my-font-ui);
  font-size: 0.78rem;
  padding: 0.15rem 0.6rem;
  margin-left: 0.4rem;
  transition: opacity var(--motion-fast) ease;
}
.spotlight-overlay__retry:hover { opacity: 0.75; }

@media (prefers-reduced-motion: reduce) {
  .spotlight-overlay,
  .spotlight-overlay__item {
    transition: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

:root {
  --scroll-progress: 0;
  --scroll-arc-opacity: 0;
}

.scroll-arc {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: var(--scroll-arc-opacity);
  transition: opacity var(--motion-slow) ease;
  overflow: visible;
  z-index: calc(var(--z-pill) + 1);
}

.scroll-arc.arc-suppressed {
  opacity: 0 !important;
  transition-duration: 0s !important;
  transition-delay: 0s !important;
}

.scroll-arc__path {
  stroke-dasharray: 1;
  stroke-dashoffset: calc(1 - var(--scroll-progress));
  transition: stroke-dashoffset var(--motion-fast) linear;
}

@media (prefers-reduced-motion: reduce) {
  .scroll-arc__path {
    transition: none;
  }
  .scroll-arc {
    transition: none;
  }
}

.shortcuts-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: var(--z-hints);
  background: var(--my-overlay-scrim);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  align-items: center;
  justify-content: center;
}

.shortcuts-overlay--open {
  display: flex;
}

.shortcuts-overlay__panel {
  position: relative;
  background: var(--my-white);
  border: 1px solid var(--my-border-color);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: 2rem 2.5rem;
  min-width: 18rem;
  max-width: 32rem;
  width: 90vw;
}

.shortcuts-overlay__title {
  font-family: var(--my-font-title);
  font-size: 1.1rem;
  font-weight: 400;
  color: var(--bs-body-color);
  margin-bottom: 1.25rem;
}

.shortcuts-overlay__section + .shortcuts-overlay__section {
  margin-top: 1.1rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--my-border-color);
}

.shortcuts-overlay__section-label {
  font-family: var(--my-font-ui);
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--my-gray-1);
  margin: 0 0 0.6rem;
}

.shortcuts-overlay__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.shortcuts-overlay__list li {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-family: var(--my-font-ui);
  font-size: 0.82rem;
  color: var(--my-gray-2);
}

.shortcuts-overlay__list li span {
  margin-left: auto;
  text-align: right;
}

.shortcuts-overlay__list kbd {
  font-family: var(--my-font-ui);
  font-size: 0.72rem;
  font-weight: 700;
  background: var(--my-silver-1);
  color: var(--my-gray-3);
  border: 1px solid var(--my-border-color);
  border-radius: var(--radius-sm);
  padding: 0.15rem 0.45rem;
  white-space: nowrap;
}
.shortcuts-overlay__list kbd .material-symbols-rounded {
  font-size: 1rem;
  vertical-align: -0.15em;
  line-height: 1;
  display: inline-block;
  font-variation-settings: 'wght' 500;
}
.shortcuts-overlay__list kbd .sym-hollow {
  font-variation-settings: 'wght' 500, 'FILL' 0;
}
.shortcuts-overlay__list kbd:has(.material-symbols-rounded) {
  padding: 0.1rem 0.15rem;
}

.shortcuts-overlay__close {
  position: absolute;
  top: 0.75rem;
  right: 1rem;
  background: none;
  border: none;
  font-size: 0.9rem;
  color: var(--my-gray-1);
  cursor: pointer;
  padding: 0.25rem;
  line-height: 1;
  transition: color var(--motion-fast) ease;
}

.shortcuts-overlay__close:hover {
  color: var(--bs-body-color);
}

@media (prefers-reduced-motion: reduce) {
  .shortcuts-overlay {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

/* ── Toast notification + page loader ────────────────────────────────────────────── */

#toast {
  position: fixed;
  bottom: calc(2rem + env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%) translateY(0.75rem);
  z-index: var(--z-toast);
  --toast-shadow: var(--shadow-md);
  background: rgba(var(--my-white-rgb), 0.92);
  color: var(--bs-body-color);
  border: 1px solid var(--my-border-color);
  border-radius: var(--radius-pill);
  padding: 0.45rem 1.1rem;
  font-family: var(--my-font-ui);
  font-size: 0.8rem;
  font-weight: 500;
  line-height: 1.35;
  white-space: normal;
  overflow-wrap: anywhere;
  text-align: center;
  max-width: min(28rem, calc(100vw - 2rem));
  box-shadow: var(--toast-shadow);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  opacity: 0;
  pointer-events: none;
  transition:
    opacity var(--motion-base) ease,
    transform var(--motion-base) ease;
}
#toast.toast--visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
#toast.toast--hiding {
  opacity: 0;
  transform: translateX(-50%) translateY(0.5rem);
}
#toast.toast--neutral {
  --toast-shadow: var(--shadow-md);
}
#toast.toast--info {
  --toast-shadow: 0 0 0 1px color-mix(in srgb, var(--my-theme-accent) 28%, transparent),
0 8px 24px color-mix(in srgb, var(--my-theme-accent) 22%, transparent);
}
#toast.toast--success {
  --toast-shadow: 0 0 0 1px rgba(46, 160, 87, 0.28),
0 8px 24px rgba(46, 160, 87, 0.24);
}
#toast.toast--warning {
  --toast-shadow: 0 0 0 1px rgba(217, 119, 6, 0.3),
0 8px 24px rgba(217, 119, 6, 0.24);
}
#toast.toast--error {
  --toast-shadow: 0 0 0 1px rgba(192, 57, 43, 0.32),
0 8px 24px rgba(192, 57, 43, 0.26);
}
#toast.toast--theme-day {
  --toast-shadow: 0 0 0 1px color-mix(in srgb, var(--my-theme-day) 28%, transparent),
0 8px 24px color-mix(in srgb, var(--my-theme-day) 22%, transparent);
}
#toast.toast--theme-night {
  --toast-shadow: 0 0 0 1px color-mix(in srgb, var(--my-theme-night) 28%, transparent),
0 8px 24px color-mix(in srgb, var(--my-theme-night) 22%, transparent);
}
@media (prefers-reduced-motion: reduce) {
  #toast { transition-duration: 0.01ms !important; }
}

#page-loader {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-pill) - 1); /* below pill + page-console; chrome stays reachable */
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--my-background);
  transition: opacity 0.45s ease;
}
#page-loader.dismissed {
  opacity: 0;
  pointer-events: none;
}
.spinner {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2.5px solid var(--my-silver-1);
  border-top-color: var(--my-black);
  animation: spin var(--motion-loader) linear infinite;
}
@keyframes spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .spinner {
    animation-duration: 3s;
  }
}


/* ── Images — load / shimmer / error states ────────────────────────────────────── */

.card-img-top,
.figure img,
.certificate img {
  background-color: var(--my-silver-2);
}
.card-img-top {
  min-height: 140px;
  object-fit: cover;
}
.certificate img {
  min-height: 40px;
}
.card-img-top:not(.img-loaded):not(.img-error),
.figure img:not(.img-loaded):not(.img-error),
.certificate img:not(.img-loaded):not(.img-error) {
  animation: rj-shimmer var(--motion-loader) ease-in-out infinite;
}
@keyframes rj-shimmer {
  0%, 100% { background-color: var(--my-silver-2); }
  50%       { background-color: var(--my-silver-1); }
}

.card-img-top.img-loaded,
.figure img.img-loaded {
  background: transparent;
  animation: none;
  opacity: 1;
  transition: opacity var(--motion-slow) ease;
}
@starting-style {
  .card-img-top.img-loaded,
  .figure img.img-loaded {
    opacity: 0;
  }
}

.img-error {
  background-color: var(--my-silver-2) !important;
  background-image: url('/resources/img_placeholder.svg') !important;
  background-repeat: no-repeat !important;
  background-position: center !important;
  background-size: clamp(28px, 35%, 56px) auto !important;
  animation: none !important;
  min-height: 60px;
  object-fit: contain !important;
  padding: 0.75rem;
  opacity: 1 !important;
}
html[data-bs-theme="dark"] .img-error {
  filter: invert(1) brightness(0.85);
}
@media (prefers-reduced-motion: reduce) {
  .card-img-top:not(.img-loaded):not(.img-error),
  .figure img:not(.img-loaded):not(.img-error),
  .certificate img:not(.img-loaded):not(.img-error) {
    animation: none;
  }
  .card-img-top.img-loaded,
  .figure img.img-loaded {
    transition: none;
  }
}

/* ── Page console — project-page chrome (#page-console family) ─────────────────── */

#page-console {
  position: fixed;
  z-index: var(--z-fixed);
  display: flex;
  align-items: flex-end;
}
#page-console.left  { left:  2.5vw; align-items: flex-start; }
#page-console.right { right: 2.5vw; align-items: flex-end; }
#page-console.top    { flex-direction: column;          top:    2.5vw; }
#page-console.bottom { flex-direction: column-reverse; bottom: calc(2.5vw + 4.5vh); }

/* Shared surface for all four page-console panels (parallel to .command-panel
   on the command-console). Individual panels add their own layout/sizing. */
.page-panel {
  border-radius: var(--panel-radius);
  background-color: rgba(var(--my-white-rgb), 0.8);
  box-shadow: var(--shadow-panel);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}

#pg-head-panel {
  position: relative;
  display: flex;
  gap: calc(0.15 * var(--signature-height));
  align-items: center;
  justify-content: space-evenly;
  height: var(--signature-height);
  padding-inline: calc(0.3 * var(--signature-height));
  transition: width var(--motion-base) ease, padding-inline var(--motion-base) ease;
}
#page-console.right #pg-head-panel { flex-direction: row-reverse; }

.pg-head__item {
  display: flex;
  background: transparent !important;
  border: none;
  padding: 0;
  width: calc(0.45 * var(--signature-height));
  height: calc(0.45 * var(--signature-height));
  align-items: center;
  justify-content: center;
  font-size: 1.15rem;
  color: var(--bs-body-color);
  cursor: pointer;
  touch-action: manipulation;
  transition: color var(--motion-fast) ease, text-shadow var(--motion-fast) ease, transform var(--motion-fast) ease;
}
.pg-head__item:hover { text-shadow: var(--glow-md); }

#pg-text-size-toggle:hover,
#page-console-toggle:hover { text-shadow: var(--glow-sm); }
/* #pg-toc-toggle glow is filter: drop-shadow on .pg-toc-icon — text-shadow has no
   effect on SVG content. See projectStyle.css #pg-toc-toggle:hover .pg-toc-icon. */

#page-console-toggle .bi { transition: transform var(--motion-base) ease; }
#page-console.left:not(.contracted)  #page-console-toggle .bi { transform: scaleX(1);  }
#page-console.right:not(.contracted) #page-console-toggle .bi { transform: scaleX(-1); }
#page-console.left.contracted  #page-console-toggle .bi { transform: scaleX(-1); }
#page-console.right.contracted #page-console-toggle .bi { transform: scaleX(1);  }

#page-console.contracted #pg-head-panel {
  width: var(--signature-height);
  padding-inline: 0;
  justify-content: center;
}
/* Expand the toggle's hit area to the full contracted pill — no dead zone. */
#page-console.contracted #page-console-toggle {
  width: 100%;
  height: 100%;
}
#page-console.contracted .pg-head__item:not(#page-console-toggle) { display: none !important; }
#page-console.contracted .pg-summoned                       { display: none !important; }

.pg-summoned {
  box-sizing: border-box;
}

@media (max-width: 768px) {
  #page-console.contracted #pg-head-panel {
    width: calc(0.7 * var(--signature-height));
    padding-inline: calc(0.08 * var(--signature-height));
    background-color: rgba(var(--my-white-rgb), 0.8);
    box-shadow: var(--shadow-panel);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    margin-inline: 0 !important;
    border-radius: calc(var(--signature-height) * 0.34);
  }
  #page-console.right.contracted #pg-head-panel { margin-right: -26px !important; }
  #page-console.left.contracted #pg-head-panel  { margin-left:  -26px !important; }
  #page-console.contracted .scroll-arc { visibility: hidden; }
}

