/* ============================================================================
   LORENZO FEDRIZZI — PORTFOLIO — PHASE 2 STYLESHEET
   ============================================================================

   Split out of index.html on 2026-09-26 (approved): the chrome kit is real
   code now and phase 3's generator will want to reuse it, so it lives in one
   file instead of inside a 25 KB page. Still no build step, still no
   framework, still opens from file://.

   THE ONE IDEA IN THIS FILE
     There is exactly one window chrome. A landing volume, a spawned picker, a
     cascaded window and the text editor are all the same markup wearing the
     same classes; they differ only by placement (.in-flow vs .float) and by
     whether the window is lit (.lit = the active window). Nothing about the
     chrome is repeated per window — that was the point of the kit.

   COLOUR — signed canon (D-022, D-040)
     near-white carries every word meant to be read; amber paints.
     base #000 · panel #050504 · amber #F0A040 · highlight #FF9830 / #FFCC50
     structure #C87020 · hairlines #C87020 at low alpha
     LIGHT MODE (D-036, built V15) is the same rule with the roles re-cut: the
     ground goes to #EEEEEE, grey carries the reading, and amber stays the fill.
     Both palettes live in the two token blocks below - dark in :root, light in
     html[data-mode="light"] - and no rule in this file names a colour directly.
     the five landing plates carry NO background of their own in either mode:
     the rectangle behind the ASCII was dropped in V15 (Lorenzo, 2026-09-26), so
     the figures sit on the window's own panel — which is also why the figures
     take ink in light mode: amber on #F7F7F7 is 1.79:1 and would vanish.

   TYPE — canonical (D-034, D-035). Rendered only at multiples of the native
   cell, never synthesised bold or italic, never scaled by transform.
     IBM EGA 9x14-2x    titles, all caps        14 / 28 / 42px
     OlivettiThin 8x16  terminal, labels, data  16 / 32px
     Departure Mono     long prose              11 / 22 / 33px

   TRANSITIONS
     --t:200ms is the single transition, and it covers hover, focus and
     selection only. Opening, raising and closing a window are INSTANT: the
     cascade snaps, with no easing and no delay (D-027). Retro to look at,
     instant to use.
   ============================================================================ */

/* ------------------------------------------------------------------ faces */
@font-face{
  font-family:'EGA 9x14';
  src:url('../fonts/oldschool-pc-fonts/Web437_IBM_EGA_9x14-2x.woff') format('woff');
  font-display:block;
}
@font-face{
  font-family:'OlivettiThin 8x16';
  src:url('../fonts/oldschool-pc-fonts/Web437_OlivettiThin_8x16.woff') format('woff');
  font-display:block;
}
@font-face{
  font-family:'Departure Mono';
  src:url('../fonts/departure-mono/DepartureMono-Regular.woff2') format('woff2'),
      url('../fonts/departure-mono/DepartureMono-Regular.woff') format('woff');
  font-display:block;
}

/* ----------------------------------------------------------------- tokens */
:root{
  --base:#000000;
  --panel:#050504;
  --amber:#F0A040;         /* large areas */
  --amber-hi:#FF9830;      /* small highlights */
  --amber-max:#FFCC50;     /* the one thing that must pop */
  --structure:#C87020;
  --hair:rgba(200,112,32,.34);
  --hair-soft:rgba(200,112,32,.15);
  --text:#F2EDE4;
  --text-2:rgba(242,237,228,.72);
  --text-3:rgba(242,237,228,.52);

  /* Keyboard focus carries no colour of its own: it gets the same amber
     treatment the pointer gives, on every control (Lorenzo, 2026-09-26). The
     cyan ring the canon's accessibility floor called for is gone — he asked for
     it off, "also in folders etc, all elements". See D-067. */

  /* the scrim on a window that is not in front. A layer, never a window
     opacity: dimming the element itself would ghost its text (SITE-CONCEPT). */
  --scrim:rgba(0,0,0,.45);

  /* ---- the pieces of the two palettes that used to be literals in the rules
     below. Naming them is what lets ONE attribute on <html> carry the whole
     theme: dark values here, light values in the block that follows this one.
     Nothing in this file is a colour literal outside these two blocks any
     more, and a grep proves it. */
  --wash-1:rgba(200,112,32,.06);      /* an unlit title bar */
  --wash-2:rgba(200,112,32,.10);      /* hover: menu item, folder, rear title */
  --wash-3:rgba(200,112,32,.16);      /* the louder hover: open menu, lit volume */
  --display:#F2EDE4;                  /* display titles: the strongest ink */
  --figure:#F0A040;                   /* the ASCII figures: amber, the drawing */
  --on-amber:#000;                    /* text and marks sitting on an amber fill */
  --on-amber-2:rgba(0,0,0,.55);       /* hairlines on an amber fill */
  --on-amber-3:rgba(0,0,0,.65);       /* the glyphs on an amber fill */
  --btn-line:rgba(242,237,228,.30);   /* window-button frame on a dark bar */
  --btn-ink:rgba(242,237,228,.45);
  --sunken:#030302;                   /* tab backs, scrollbar tracks */
  --panel-2:#0a0a09;                  /* a menu floating above a panel */
  --lit-bg:#080807;                   /* body of the focused landing volume */
  --thumb:rgba(200,112,32,.45);       /* scrollbar thumb */
  --scan:rgba(0,0,0,.55);             /* scanline ink - chrome only */
  --scan-op:.45;
  --glow:0 0 6px rgba(240,160,64,.30);/* the one glow, on the figures only */
  --desk-scrim:rgba(0,0,0,.5);        /* the wash behind an open window */
  --boot-ink:#F0A040;
  --boot-hi:#FFCC50;
  --link:#FFCC50;
  --state-ink:#FF9830;                /* the one state word, /MOUNTED */
  --mark:#F0A040;                     /* the single tick in the colophon */
  --ctl-hi:#F0A040;                   /* a control's hover: arrows, pager */

  /* the plate rectangle's shades used to live here (--pl-1..5, pinned to one
     value in V14). Removed in V15: there is no rectangle behind the figures in
     either mode any more (Lorenzo, 2026-09-26). */

  /* the one transition. nothing interactive is slower than this. */
  --t:200ms;
}

/* ============================================================================
   LIGHT MODE - D-036, built 2026-09-26 (V15). OPTION 1: AMBER AS PAINT.
   ============================================================================

   Amber never sets text on a light ground: #F0A040 on #EEEEEE is 1.85:1 and
   fails outright. So amber changes ROLE rather than being weakened - it becomes
   the fill (title bars, washes, selections), and grey carries every word that
   is meant to be read. The palette is measured from Lorenzo's Departure Mono
   light reference, not guessed: ground #EEEEEE (neutral - it is NOT warm bone;
   a warm ground puts the surface in amber's own hue family and the amber stops
   reading as amber), panel #F7F7F7, ground-2 #E8E8E8.

   INK, AND WHY THERE ARE TWO GREYS. #666666 carries the reading (4.95:1 on the
   ground, 4.75:1 on a panel) and #333333 is reserved for display titles and for
   text knocked out of an amber fill (5.90:1) - which is what --on-amber does
   here, where dark mode knocks out to black. #8A8A8A (2.98:1) is the muted
   register the hints and the metadata sit in, and #AAAAAA (2.00:1) is held for
   decoration only. The accent that MUST be text - a link, the state word -
   gets #8A4A0C (5.90:1), which is Option 1's own escape hatch.

   WHAT FOLLOWS THE PLATE RATHER THAN THE PAGE. The five landing plates stay
   dark in light mode: the plate is the screen, and the screen is the one thing
   that does not flip, because the amber figures are 1.85:1 on a light ground
   and would stop being a drawing. So --plate-ink stays near-white, and the
   caption inside a plate does not follow --text.

   DROPPED, PER THE CANON: the phosphor glow, entirely - meaningless on a light
   ground. Scanlines invert to #000 at ~5.5% alpha and stay chrome-only.
   ============================================================================ */
html[data-mode="light"]{
  --base:#EEEEEE;
  --panel:#F7F7F7;
  --amber:#F0A040;                  /* still the fill */
  --amber-hi:#C87020;               /* small highlights become structure */
  --amber-max:#FFCC50;              /* still the fill that must pop */
  --structure:#C87020;
  --hair:rgba(200,112,32,.55);      /* amber-tinted: the frames keep the identity */
  --hair-soft:rgba(200,112,32,.30);
  --text:#666666;
  --text-2:#666666;                 /* every control label is read, so it is ink */
  --text-3:#8A8A8A;
  --display:#333333;
  --figure:#333333;                 /* WITH NO RECTANGLE BEHIND THEM the amber
                                       figures would be 1.79:1 on the panel, so in
                                       light mode the drawing takes ink and the
                                       amber lives in the frames, the washes and
                                       the title bars instead */
  --wash-1:rgba(240,160,64,.18);
  --wash-2:rgba(240,160,64,.26);
  --wash-3:rgba(240,160,64,.36);
  --on-amber:#333333;
  --on-amber-2:rgba(51,51,51,.55);
  --on-amber-3:rgba(51,51,51,.70);
  --btn-line:rgba(51,51,51,.35);
  --btn-ink:rgba(51,51,51,.55);
  --sunken:#E8E8E8;
  --panel-2:#FFFFFF;                /* the one value the canon lacked: a floating
                                       menu needs a layer above the panel */
  --lit-bg:#FCFCFC;
  --thumb:rgba(200,112,32,.60);
  --scan:rgba(0,0,0,.055);
  --scan-op:1;
  --glow:none;
  --scrim:rgba(255,255,255,.55);    /* a rear window is veiled, not darkened */
  --desk-scrim:rgba(255,255,255,.50);
  --boot-ink:#666666;               /* the boot is text, so the boot is ink */
  --boot-hi:#333333;
  --link:#8A4A0C;
  --state-ink:#8A4A0C;
  --mark:#C87020;
  --ctl-hi:#C87020;
}

/* ============================================================================
   THE SWITCH - a two-state segment at the right end of the colophon, in the
   same 16px register as the hints beside it (Lorenzo, 2026-09-26).

   No frame around the group and no padding above or below the text: the box is
   exactly 16px tall, so its glyphs sit on the same line as CLICK TO OPEN ... and
   the amber fill alone says which half is on. A 1px frame would have cost 2px of
   height and broken that. Keyboard reaches both halves like any button; nothing
   lights up on focus, because nothing on this site does (D-067).
   ============================================================================ */
.modeswitch{
  margin-left:auto;
  display:flex;align-items:center;
  font-size:16px;line-height:16px;
}
.modeswitch button{
  font-family:inherit;font-size:16px;line-height:16px;font-weight:400;
  height:16px;padding:0 9px;
  background:none;border:0;color:var(--text-3);
  cursor:pointer;letter-spacing:0;
  transition:color var(--t) linear,background-color var(--t) linear;
}
.modeswitch button:hover{color:var(--text);background:var(--wash-2)}
.modeswitch button.on{background:var(--amber);color:var(--on-amber)}


*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  background:var(--base);
  color:var(--text);
  font-family:'OlivettiThin 8x16',monospace;
  font-size:16px;
  line-height:16px;
  -webkit-font-smoothing:none;
  text-rendering:geometricPrecision;
  font-synthesis:none;              /* no faked bold, no faked italic */
  font-variant-ligatures:none;
  overflow-x:hidden;
}
/* Selection is off across the mock operating system: a stray click-drag while
   exploring should not smear a highlight over the interface. Anything a
   visitor may legitimately want to copy carries .selectable. */
body{-webkit-user-select:none;user-select:none}
.selectable{-webkit-user-select:text;user-select:text;cursor:text}
::selection{background:var(--amber-max);color:var(--on-amber)}

/* keyboard focus, everywhere: no indicator of any kind (Lorenzo, 2026-09-26 —
   "I don't want keyboard focus at all. only pointer. keyboard works for changing
   plates or icon, but no amber"). The keys still drive everything: arrows move
   between folder items and between plates, Enter opens, Escape closes. Nothing
   lights up. The only focus treatment on the site is the pointer's own. */
:focus{outline:none}
:focus-visible{outline:none}

/* ------------------------------------------------------ chrome scanlines */
/* chrome only. never over a plate, never over prose. */
.scan{position:relative}
.scan::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:repeating-linear-gradient(to bottom,var(--scan) 0 1px,rgba(0,0,0,0) 1px 3px);
  opacity:var(--scan-op);
}

/* ----------------------------------------------------------- boot screen */
#boot{
  position:fixed;inset:0;z-index:100;
  background:var(--base);
  padding:30px 34px;
  color:var(--boot-ink);
  font-size:16px;line-height:16px;
}
#boot .l{display:block;opacity:0;animation:lineIn 120ms steps(1) forwards}
#boot .l:nth-child(1){animation-delay:0ms}
#boot .l:nth-child(2){animation-delay:120ms}
#boot .l:nth-child(3){animation-delay:250ms}
#boot .l:nth-child(4){animation-delay:380ms}
#boot .l:nth-child(5){animation-delay:480ms}
#boot .l:nth-child(6){animation-delay:600ms}
#boot .l:nth-child(7){animation-delay:740ms}
#boot .dim{color:var(--text-3)}
#boot .hi{color:var(--boot-hi)}
#boot .cursor{
  display:inline-block;width:8px;height:15px;
  background:var(--boot-hi);vertical-align:-3px;
  animation:blink 1s steps(1) infinite;
}
@keyframes lineIn{to{opacity:1}}
@keyframes blink{0%,49%{opacity:1}50%,100%{opacity:0}}
body.booted #boot{display:none}

/* ---------------------------------------------------------------- layout */
#desktop{
  /* 100vh, not 100%: GLightbox ships `.glightbox-open{height:auto}` for wide
     screens and puts that class on html and body while a plate is open, which
     collapses this element's percentage height and let the colophon — and with it
     the bottom orange line — float up into the middle of the screen. A viewport
     unit does not care what the library does to its ancestors. */
  min-height:100vh;
  padding:22px 24px 30px;
  display:flex;flex-direction:column;gap:16px;
}

header.masthead{
  display:flex;align-items:baseline;gap:16px;flex-wrap:wrap;
  padding-bottom:10px;
  border-bottom:1px solid var(--hair);
}
.mast-name{
  font-family:'EGA 9x14',monospace;
  font-size:28px;line-height:28px;font-weight:400;
  color:var(--display);           /* the strongest ink in either mode */
  white-space:nowrap;
}
.mast-meta{
  margin-left:auto;
  color:var(--text-3);
  font-size:16px;line-height:22px;
  text-align:right;
}

.hintline{display:flex;gap:14px;flex-wrap:wrap;color:var(--text-3);font-size:16px;line-height:16px}

/* five volumes, equal width, one row */
#volumes{
  display:grid;
  grid-template-columns:repeat(5,minmax(0,1fr));
  gap:14px;
}

/* ==========================================================================
   THE CHROME KIT — one set of parts, every window
   ========================================================================== */

.win{
  background:var(--panel);
  border:1px solid var(--hair);
  display:flex;flex-direction:column;
  min-width:0;
  color:var(--text);
  font-size:16px;line-height:16px;
}
.win.in-flow{min-height:430px;cursor:pointer}
.win.float{
  position:absolute;
  /* No drop shadow, no bevel: period-correct 90s windows sit on the desktop
     with a frame and nothing else, and the canon bans card shadows. The
     opaque panel over the darkened desktop is what separates them. */
  background:var(--panel);
}

/* ---- title bar */
.win-title{
  display:flex;align-items:center;gap:10px;
  padding:5px 7px;
  border-bottom:1px solid var(--hair);
  background:var(--wash-1);
  transition:background-color var(--t) linear;
  flex:0 0 auto;
}
.win-ico{color:var(--amber-hi);flex:0 0 auto}
.win-name{
  font-size:16px;line-height:16px;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.win-btns{margin-left:auto;display:flex;gap:5px;flex:0 0 auto}
.win-btns button,
.win-btns i{
  font-family:inherit;font-size:16px;line-height:9px;
  font-style:normal;font-weight:400;
  width:15px;height:13px;padding:0;
  border:1px solid var(--btn-line);
  background:none;color:var(--btn-ink);
  text-align:center;display:block;
}
.win-btns button{cursor:pointer;transition:border-color var(--t) linear,color var(--t) linear}
.win-btns button:hover{border-color:var(--amber-hi);color:var(--amber-hi)}
/* On a landing volume the three glyphs are drawn, not controls: the whole
   volume is the control (D-043). Inside a spawned window they are real buttons. */
.win.in-flow:hover .win-btns i{border-color:var(--structure);color:var(--structure)}

/* ---- the lit window: the landing volume that is open, or the front window
   of the cascade. Drawn the way a window manager draws the active window —
   the title bar floods amber and its text knocks out to black (D-043). */
.win.lit{border-color:var(--amber-hi)}
.win.lit > .win-title{background:var(--amber);border-bottom-color:var(--amber)}
.win.lit > .win-title .win-name{color:var(--on-amber)}
.win.lit > .win-title .win-ico{color:var(--on-amber)}
.win.lit > .win-title .win-btns button,
.win.lit > .win-title .win-btns i{border-color:var(--on-amber-2);color:var(--on-amber-3)}
.win.lit > .win-title .win-btns button:hover{border-color:var(--on-amber);color:var(--on-amber)}

/* ---- menu bar */
.win-menu{
  display:flex;gap:2px;align-items:stretch;
  padding:3px 5px;
  border-bottom:1px solid var(--hair-soft);
  flex:0 0 auto;flex-wrap:wrap;
}
.mi{position:relative}
.mi > button{
  font-family:inherit;font-size:16px;line-height:16px;font-weight:400;
  background:none;border:1px solid transparent;
  color:var(--text-2);padding:2px 7px;cursor:pointer;
}
.mi > button:hover,.mi.open > button{border-color:var(--hair);color:var(--text);background:var(--wash-2)}
.dd{
  position:absolute;top:100%;left:0;z-index:5;min-width:190px;
  background:var(--panel-2);border:1px solid var(--hair);
  padding:3px 0;display:none;
}
.mi.open .dd{display:block}
.dd button{
  display:block;width:100%;text-align:left;
  font-family:inherit;font-size:16px;line-height:16px;font-weight:400;
  background:none;border:0;color:var(--text-2);
  padding:6px 12px;cursor:pointer;white-space:nowrap;
}
.dd button:hover{background:var(--wash-3);color:var(--text)}
.dd button[disabled]{color:var(--text-3);cursor:default}
.dd button[disabled]:hover{background:none;color:var(--text-3)}
.dd hr{border:0;border-top:1px solid var(--hair-soft);margin:3px 0}

/* ---- toolbar and location bar */
.win-tool{
  display:flex;gap:6px;align-items:center;
  padding:5px 7px;border-bottom:1px solid var(--hair-soft);
  flex:0 0 auto;flex-wrap:wrap;
}
.win-tool button{
  font-family:inherit;font-size:16px;line-height:16px;font-weight:400;
  background:none;border:1px solid var(--hair-soft);
  color:var(--text-2);padding:3px 9px;cursor:pointer;
  transition:border-color var(--t) linear,color var(--t) linear;
}
.win-tool button:hover{border-color:var(--hair);color:var(--text)}
.win-tool button[disabled]{color:var(--text-3);border-color:var(--hair-soft);cursor:default}
.win-tool .sep{width:1px;align-self:stretch;background:var(--hair-soft);margin:0 3px}
.win-loc{
  display:flex;align-items:center;gap:8px;
  padding:4px 7px;border-bottom:1px solid var(--hair-soft);
  color:var(--text-2);font-size:16px;line-height:16px;
  flex:0 0 auto;
}
.win-loc .path{margin-left:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---- body */
.win-body{flex:1 1 auto;min-height:0;position:relative;overflow:auto}

/* ---- status bar */
.win-status{
  display:flex;gap:10px;align-items:center;
  padding:5px 7px;border-top:1px solid var(--hair);
  color:var(--text-3);font-size:16px;line-height:16px;
  flex:0 0 auto;
}
.win-status .right{margin-left:auto}
.win-status .lit{color:var(--state-ink)}
.win-status .cut{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---- the rear scrim: a layer over the whole window, never an opacity */
.win-scrim{
  position:absolute;inset:0;pointer-events:none;
  background:var(--scrim);opacity:0;
}
.win.rear > .win-scrim{opacity:1}
.win.rear > .win-title{background:var(--wash-2)}

/* ---- the ascii plate area of a landing volume */
.plate{
  flex:1;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;
  padding:16px 10px;
  overflow:hidden;
}
/* The plate's own rectangle is GONE — no background behind the figures in either
   mode (Lorenzo, 2026-09-26). The five volumes were five grey rectangles behind
   five drawings; the drawings and the frames were always what told them apart, so
   the rectangle had nothing left to do and it read as a stray box inside a window
   in light mode. The .p1...p5 classes stay on the markup as the volumes' own
   identity, and they carry no styling. */

/* the ASCII figures. the glow lives here and nowhere else. */
.ascii{
  white-space:pre;
  color:var(--figure);
  font-size:16px;line-height:16px;
  text-shadow:var(--glow);
  overflow:hidden;margin:0;
  -webkit-user-select:none;user-select:none;   /* it is a drawing, not text */
  -webkit-user-drag:none;
}

/* the figure's caption, below the drawing and inside the same box: white like
   the rest of the page's text. It is its own element rather than the last line
   of the drawing, and it fades in when the drawing finishes. Without JavaScript
   it is visible from the start, or the landing would look captioned by nothing. */
.ascii-label{
  font-size:16px;line-height:16px;
  color:var(--text);              /* the plate rectangle is gone: the caption
                                     sits on the window's own panel now */
  opacity:0;
  transition:opacity var(--t) linear;
  -webkit-user-select:none;user-select:none;
}
.ascii-label.on{opacity:1}

/* ---- landing volume states (D-043: hover selects, single click opens) */
.win.in-flow.focused{border-color:var(--amber-hi);background:var(--lit-bg)}
.win.in-flow.focused .win-title{background:var(--wash-3)}
/* Hovering spotlights one volume by dimming the rest — never the lit one:
   moving the pointer must not make the active window look switched off. */
#volumes.has-focus .win.in-flow:not(.focused):not(.lit){opacity:.5}

/* A DIMMED DESK IS HOVER-DEAD, AND CLICK-ALIVE (Lorenzo, 2026-09-26: "make it so
   that anything below the dim doesn't react to pointer hovering - only to click
   (to exit)").

   Two rules, because the wash sits at two heights. With a window stack up it is
   behind the windows (z 15) and only the landing is under it; with a plate open
   it moves above the windows (z 30). Elements below the wash leave hit-testing
   entirely: no hover spotlight, no folder item lighting up under the dim, no
   cursor change. A click still reaches the page underneath and dismisses — which
   is what it looks like it does. The plate and its arrows are above the wash and
   keep their hover.

   The second rule is the guarantee rather than the mechanism: with a plate open
   the lightbox container already covers the whole viewport, so the window layer
   cannot be reached regardless — this says so out loud instead of relying on that
   coincidence staying true. */
body.has-windows #volumes .win.in-flow{pointer-events:none;cursor:default}
body.viewer-open #windows{pointer-events:none}

/* ==========================================================================
   THE WINDOW LAYER — spawned windows float over the desktop
   ========================================================================== */

#windows{
  position:fixed;inset:0;z-index:20;
  pointer-events:none;      /* the desktop underneath stays clickable */
}
#windows > .win{pointer-events:auto}
/* ONLY THE FRONT WINDOW IS REACTIVE (Lorenzo, 2026-09-26: "when two folders (like
   portfolio/retail/) are open in a stack, only the top one is reactive. right now
   I managed to click on an icon in the back folder (portfolio) while the top
   (retail) was open and the layout softlocked"). A window that has been pushed
   back is not a target any more: its folders, menus and title-bar buttons are
   dead. A click on it lands on the desktop instead — which now means "go back one
   level", so the window you aimed at comes forward because the one above it
   closes. That is the same gesture as a real folder stack, and it cannot open a
   child from a window that is not in front. */
#windows > .win.rear{pointer-events:none}
.win.float:not(.lit){cursor:default}

/* The wash that puts the desktop back when a window is up — a layer over the
   desktop, never an opacity on it, because dimming the element itself would
   ghost every word on it. Instant, like the cascade: no transition.

   ITS HEIGHT IS THE DISMISS BAND, not the viewport (Lorenzo, 2026-09-26): JS
   sets top and bottom from the masthead's bottom hairline and the colophon's top
   hairline, the same two measurements the click rule uses, so the masthead and
   the colophon stay undimmed — exactly as they are when nothing is open, because
   clicking them does nothing either. `inset:0` is the fallback if that has not
   run yet. */
#desk-scrim{
  position:fixed;inset:0;z-index:15;
  background:var(--desk-scrim);
  opacity:0;pointer-events:none;
}
body.has-windows #desk-scrim,
body.viewer-open #desk-scrim{opacity:1}

/* WHILE A PLATE IS OPEN THE WASH GOES ABOVE THE WINDOWS, not behind them
   (Lorenzo, 2026-09-26, from a screenshot: the desk and the ASCII behind were
   dimmed but "the most upfront window (hospitality) is full color. should be
   dimmed as well when the photo is open. only top and bottom bar with no dim at
   all"). Behind them — where it sits for a window stack on its own — it dims the
   desktop and leaves the front window crisp, which is right when the front window
   is the thing you are looking at. With a plate open the plate is the thing you
   are looking at, so everything in the band dims together: one layer, moved, not
   a second one added. The plate itself is inside the lightbox (z 999999) and the
   two bars are outside the wash's rectangle, so neither is touched. */
body.viewer-open #desk-scrim{z-index:30}

/* THE SWITCH SITS ABOVE WHATEVER IS OPEN (Lorenzo, 2026-09-26). Two layers cover
   the viewport and both used to swallow the click before the button saw it: the
   lightbox's container (`fixed; inset:0`, z-index 999999) while a plate is open,
   and `#caseview` (`fixed; inset:0`, z-index 25) while a case study is open — which
   is why the switch went dead in a case study and clicking it closed the case
   instead. It is lifted above both, and above the window layer, whenever anything
   is open: "the dark/light switch should be always active, and not be a region
   that when clicked closes the plate slideshow".

   Only the switch is lifted, not the whole bar: the plate's own close button lives
   in the top-right corner inside the masthead's rectangle, so raising the masthead
   over the plate layer would have killed that button instead. Nothing is covered by
   the lift — the plate box is capped at 100vh-210px and the case view at 755px, so
   neither ever reaches the bottom bar. It is NOT lifted while nothing is open, so
   the boot overlay keeps anything from being clickable through it. */
body.has-windows .modeswitch,
body.viewer-open .modeswitch{position:relative;z-index:1000000}

/* ==========================================================================
   PICKER — the fake Explorer
   ========================================================================== */

.pick{padding:12px}
.pick.grid{
  display:grid;gap:8px;
  grid-template-columns:repeat(auto-fill,minmax(118px,1fr));
  align-items:start;align-content:start;
}
.obj{
  display:flex;flex-direction:column;align-items:center;gap:6px;
  padding:9px 6px;background:none;border:1px solid transparent;
  font-family:inherit;font-size:16px;line-height:16px;font-weight:400;
  color:var(--text-2);cursor:pointer;text-align:center;text-decoration:none;
  transition:border-color var(--t) linear,background-color var(--t) linear;
}
/* the folder / plate item. `align-items:start` on the grid matters: without it
   every item stretches to the height of the tallest cell in its row, and the
   amber selection ran the full height of the folder instead of hugging the icon
   and its two lines of text (Lorenzo, 2026-09-26, from a screenshot). */
.obj:hover,.obj.sel{border-color:var(--amber-hi);background:var(--wash-2);color:var(--text)}
.obj-ico{width:64px;height:48px;display:flex;align-items:center;justify-content:center;flex:0 0 auto}
.obj-ico img,.obj-ico svg{max-width:64px;max-height:48px;display:block}
.obj-lab{width:100%;overflow-wrap:anywhere;color:inherit}
.obj-meta{color:var(--text-3);font-size:16px;line-height:16px}

/* list view — the same objects, one per row (View menu toggles it) */
.pick.list{display:block;padding:6px 0}
.pick.list .obj{
  flex-direction:row;align-items:center;gap:10px;
  padding:4px 10px;border-left:1px solid transparent;border-right:0;border-top:0;border-bottom:0;
}
.pick.list .obj-ico{width:22px;height:18px}
.pick.list .obj-ico img,.pick.list .obj-ico svg{max-width:22px;max-height:18px}
.pick.list .obj-lab{width:auto;flex:1 1 auto;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pick.list .obj-meta{flex:0 0 auto}

.pick-empty{padding:22px 14px;color:var(--text-3);font-size:16px;line-height:24px}

/* ==========================================================================
   EDITOR — the Namo anatomy, dark
   ========================================================================== */

.win-tabs{
  display:flex;gap:0;align-items:flex-end;
  padding:6px 6px 0;border-bottom:1px solid var(--hair-soft);
  flex:0 0 auto;overflow-x:auto;
}
.tab{
  font-family:inherit;font-size:16px;line-height:16px;font-weight:400;
  background:var(--sunken);border:1px solid var(--hair-soft);border-bottom:0;
  color:var(--text-3);padding:5px 11px 6px;cursor:pointer;white-space:nowrap;
  transition:color var(--t) linear,border-color var(--t) linear;
}
.tab + .tab{margin-left:-1px}
.tab:hover{color:var(--text)}
.tab.on{background:var(--panel);border-color:var(--hair);color:var(--text);position:relative;z-index:1}

/* The editor's text-size pair, at the far right of the tab row and level with the
   tabs. The editor has no menu bar and no toolbar row any more. */
.tabs-right{
  margin-left:auto;flex:0 0 auto;
  display:flex;gap:6px;align-items:center;
  padding:0 0 4px 12px;
}
.tabs-right button{
  font-family:inherit;font-size:16px;line-height:16px;font-weight:400;
  background:none;border:1px solid var(--hair-soft);color:var(--text-2);
  padding:3px 10px;cursor:pointer;
  transition:border-color var(--t) linear,color var(--t) linear;
}
.tabs-right button:hover{border-color:var(--hair);color:var(--text)}

.doc{
  font-family:'Departure Mono',ui-monospace,monospace;
  font-size:22px;line-height:33px;      /* 22 and 33: the face's own steps */
  color:var(--text);
  padding:26px 30px 40px;
  max-width:820px;
}
.doc.big{font-size:33px;line-height:44px}
.doc-note{
  display:block;margin-bottom:22px;padding-bottom:14px;
  border-bottom:1px solid var(--hair-soft);
  color:var(--text-3);font-size:22px;line-height:33px;
}
.doc p{margin:0 0 22px}
.doc p:last-child{margin-bottom:0}
.doc .sig{color:var(--text-2)}
.doc a{color:var(--link);text-decoration:none;border-bottom:1px solid var(--hair)}
.doc a:hover{border-bottom-color:var(--amber-max)}

/* a real scrollbar, drawn to fit the register */
.win-body::-webkit-scrollbar{width:14px;height:14px}
.win-body::-webkit-scrollbar-track{background:var(--sunken);border-left:1px solid var(--hair-soft)}
.win-body::-webkit-scrollbar-thumb{background:var(--thumb);border:1px solid var(--hair)}
.win-body::-webkit-scrollbar-thumb:hover{background:var(--amber)}

/* ==========================================================================
   VIEWER — GLightbox, restyled to the canon
   ========================================================================== */

.glightbox-container{background:transparent;font-family:'OlivettiThin 8x16',monospace}

/* D-037, D-063 and D-065: the plate sits inside the same 1524 x 755 box the case
   study uses, and the caption sits BELOW that box, outside it.

   THE BOX MUST NOT MOVE. It used to: the slide block is centred as a whole, so a
   caption that wrapped to three lines on a portrait plate made the block taller
   and pushed the box up, and a one-line caption let it drop back down. The box
   tracked the text. Two rules fix it, and neither of them fights the library's
   own layout: the caption NEVER wraps (one line per element, ellipsis if it must),
   so its height is constant, and the box keeps a 2:1 ratio that shrinks on a
   shorter screen — a browser with chrome leaves about 890px of viewport, not
   1080, and the whole thing still has to fit without scrolling.

   !important, deliberately: the library writes inline width/height on these
   elements, so a plain rule loses. */
.glightbox-container{
  --cap-w: min(1524px, calc(100vw - 120px));
  --cap-h: min(755px, calc(100vh - 210px));
}
/* THE FRAME HUGS THE PLATE (Lorenzo, 2026-09-26). The box is a LIMIT, not a
   shape: previously the plate lived inside a permanent 2:1 black rectangle, so a
   portrait plate sat in a wide empty black band. Now the media box shrinks to
   the plate and the amber hairline sits on the plate itself — no black padding,
   the plate scaled to whichever cap it reaches first. */
.glightbox-container .gslide-media{
  width:fit-content !important;
  height:auto !important;
  max-width:none !important;max-height:none !important;
  margin:0 auto !important;
  display:block !important;
  background:none;
  border:0;
}
.glightbox-container .gslide-image{
  width:auto;height:auto;
  display:block;
}
.glightbox-container .gslide-image img{
  width:auto !important;height:auto !important;
  max-width:var(--cap-w) !important;
  max-height:var(--cap-h) !important;
  border:1px solid var(--hair);
  display:block;
}
/* THE CAPTION DOES NOT MOVE (Lorenzo, 2026-09-26). It is the full width of the
   viewer and centred, so its left edge is the same on every plate. It used to
   take the plate's own width — the library writes an inline max-width from the
   image — so a portrait plate's caption sat 380px further right than a landscape
   plate's, and it jumped sideways on every change. A stylesheet !important beats
   an inline non-important declaration, which is what makes this hold.

   One line per element, never wrapped: that keeps its height constant, which is
   what stops the plate's position depending on how long the caption is. */
.glightbox-container .gslide-description{
  width:100% !important;
  max-width:none !important;
  margin:0 !important;
  text-align:center;
}
.glightbox-container .gdesc-inner{padding:9px 0 0 !important}
.glightbox-container .gslide-title,
.glightbox-container .gslide-desc{
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.glightbox-container .gslide-description{background:none}
.glightbox-container .gslide-title{
  font-family:'Departure Mono',ui-monospace,monospace;
  font-size:22px;line-height:33px;color:var(--text);
  margin:0 0 4px;
}
.glightbox-container .gslide-desc{
  font-family:'OlivettiThin 8x16',monospace;
  font-size:16px;line-height:24px;color:var(--text-3);margin:0;
}
.glightbox-container .gbtn{
  color:var(--text-2);background:none;border:1px solid var(--hair-soft);
  width:40px;height:36px;line-height:34px;text-align:center;
  border-radius:0;font-size:18px;opacity:1;
  transition:border-color var(--t) linear,color var(--t) linear;
}
.glightbox-container .gbtn:hover,.glightbox-container .gbtn:focus{
  background:none;border-color:var(--ctl-hi);color:var(--ctl-hi);opacity:1;
}
.glightbox-container .gclose{top:14px;right:14px}
.glightbox-container .gloader{border-color:var(--hair);border-right-color:var(--amber)}
.glightbox-container .goverlay{display:none}   /* the ground is bare by design (D-064) */
.glightbox-clean .gslide-media{box-shadow:none}
.glightbox-clean .gslide-title,.glightbox-clean .gslide-desc{font-family:inherit}
.glightbox-mobile .glightbox-container .gslide-title{font-size:22px}

/* ---------------------------------------------------------------- two-up pairs
   D-037, built in V14. Two consecutive plates of the SAME PROJECT whose
   orientation is portrait or square become ONE STEP of the archive slideshow:
   754 CSS px each with a 16px gutter (754 + 16 + 754 = 1524), one caption line
   under the pair, and the pair counts as a single step for the arrows and for
   the endless loop. Never a caption under each plate, and never a pair across
   two projects.

   The step is a GLightbox INLINE slide rather than an image slide: the two
   plates are real <img> elements, cloned by the library out of a hidden holder
   in site.js. So there is no composite file to generate, no extra encode, and
   the exported plates stay exactly as IMAGE-EXPORT-SPEC.md specifies them.

   A tall portrait reaches the HEIGHT cap first and takes less than 754 of
   width, because D-037 is explicit that nothing may exceed the cap in either
   direction. On a 1920-wide window: a square pair renders 754 x 754 each, a
   1:1.5 portrait pair renders 503 x 755 each, a 1:2.17 pair 348 x 755 each.

   WHY THESE RULES LOOK OVER-WEIGHTED. The library ships
   `.ginlined-content{overflow:auto;display:block!important;opacity:1}` and
   `.gslide-inline{background:#fff;padding:20px on the inner box}`. A plain
   `.lf-pair{display:flex}` LOSES to that on specificity, and the two plates
   stack vertically — which is exactly what happened on the first build of this
   rule. Same lesson as fitViewer(): the library's own declarations win unless
   they are beaten on their own terms, so the pair is asserted with matching
   specificity AND !important, and the white ground and the 20px of inner
   padding are removed so the pair sits flush like a single plate. */
.glightbox-container .gslide-inline{
  background:none;text-align:center;max-height:none;overflow:visible;
}
.glightbox-container .gslide-inline .ginlined-content.lf-pair{
  display:flex !important;
  flex-direction:row;
  align-items:center;justify-content:center;
  gap:16px;
  width:auto !important;height:auto !important;max-width:none !important;
  max-height:none !important;
  padding:0 !important;overflow:visible;
  margin:0 auto;
}
.glightbox-container .gslide-inline .ginlined-content.lf-pair img{
  display:block;
  width:auto;height:auto;
  max-width:754px;
  max-height:var(--cap-h);
  border:1px solid var(--hair);
}

/* ==========================================================================
   DESKTOP STATUS LINE and colophon
   ========================================================================== */

#deskbar{
  border:1px solid var(--hair);
  border-left:2px solid var(--amber-hi);
  background:var(--panel);
  padding:11px 13px;
  color:var(--text-2);
  font-size:16px;line-height:24px;
  min-height:78px;
}
#deskbar b{font-weight:400;color:var(--display)}
#deskbar .path{color:var(--link)}
#deskbar .ph{color:var(--text-3)}
#deskbar .row{display:flex;gap:10px;flex-wrap:wrap}
#deskbar .row + .row{margin-top:4px}
#deskbar .right{margin-left:auto;color:var(--text-3)}

footer.colophon{
  margin-top:auto;
  padding-top:10px;
  border-top:1px solid var(--hair-soft);
  display:flex;gap:16px;flex-wrap:wrap;
  color:var(--text-3);
  font-size:16px;line-height:16px;
}
footer.colophon .lit{color:var(--text-2)}
footer.colophon .mark{color:var(--mark)}   /* one amber tick, nothing more */

/* ==========================================================================
   THE CASE STUDY — a split view over the whole viewport
   plates on the left, text on the right, no folder structure inside it
   ========================================================================== */

#caseview{
  position:fixed;inset:0;z-index:25;
  display:flex;align-items:center;justify-content:center;
  padding:24px;
}
#caseview[hidden]{display:none}
/* D-037: the same box the plates live in — a hard 1524 x 755 cap, 2:1. The case
   study is a window sitting on the desktop with the ground visible around it,
   not a full page: a case file that runs edge to edge throws away the frame the
   plates were built around. */
.case{
  display:flex;flex-direction:column;
  width:min(1524px,100%);
  height:min(755px,100%);
  background:var(--base);
  border:1px solid var(--hair);
}
.case-bar{
  display:flex;align-items:center;gap:10px;
  padding:7px 9px;flex:0 0 auto;
  background:var(--amber);border-bottom:1px solid var(--hair);
}
.case-name{
  font-family:'EGA 9x14',monospace;
  font-size:14px;line-height:14px;color:var(--on-amber);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.case-bar .win-btns button{border-color:var(--on-amber-2);color:var(--on-amber-3)}
.case-bar .win-btns button:hover{border-color:var(--on-amber);color:var(--on-amber)}

.case-body{flex:1 1 auto;display:flex;min-height:0}
.case-left{
  flex:1 1 58%;min-width:0;
  display:flex;flex-direction:column;justify-content:center;gap:12px;
  padding:20px;border-right:1px solid var(--hair);
}
.case-right{flex:0 0 42%;min-width:0;overflow:auto}

/* a page with no image keeps the two-column shape — an empty stage on the left,
   the text on the right — because that is the layout Lorenzo wants for a case
   study (D-066). The page sequence stays; only the text-only full-width variant
   is gone. */
.case-body.image-only .case-left{flex:1 1 auto;border-right:0}
.case-body.image-only .case-right{display:none}
.case-stage-empty{
  flex:1 1 auto;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;
  text-align:center;
}

/* the page arrows live at the foot of the panel and loop in both directions */
.case-foot{
  display:flex;align-items:center;gap:18px;flex:0 0 auto;
  padding:10px 14px;border-top:1px solid var(--hair-soft);
}
.case-foot .pager-nav{flex:0 0 auto}
.case-foot-note{
  margin-left:auto;min-width:0;
  color:var(--text-3);font-size:16px;line-height:16px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.case-heading{
  font-family:'EGA 9x14',monospace;
  font-size:14px;line-height:14px;color:var(--text-2);letter-spacing:1px;
  margin:0 0 20px;
}

.pager-stage{flex:1 1 auto;display:flex;align-items:center;justify-content:center;min-height:0}
.pager-stage img{max-width:100%;max-height:100%;object-fit:contain;border:1px solid var(--hair)}
.pager-nav{display:flex;align-items:center;justify-content:center;gap:16px;flex:0 0 auto}
.pager-nav button{
  font-family:inherit;font-size:16px;line-height:16px;font-weight:400;
  background:none;border:1px solid var(--hair-soft);color:var(--text-2);
  padding:3px 12px;cursor:pointer;
  transition:border-color var(--t) linear,color var(--t) linear;
}
.pager-nav button:hover{border-color:var(--ctl-hi);color:var(--ctl-hi)}
.pager-count{color:var(--text-3);font-size:16px;line-height:16px}
.pager-cap{
  flex:0 0 auto;text-align:center;
  font-size:16px;line-height:24px;color:var(--text-2);
}
.pager-cap b{font-weight:400;color:var(--display)}

.pager-empty{
  flex:1 1 auto;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;
  border:1px solid var(--hair-soft);padding:30px 22px;text-align:center;
}
.pager-empty-line{
  font-family:'EGA 9x14',monospace;font-size:14px;line-height:14px;
  color:var(--text-2);letter-spacing:1px;
}
.pager-empty-note{color:var(--text-3);font-size:16px;line-height:24px;max-width:44ch}

/* the same long-form face and steps as the editor's documents */
.case-text{
  font-family:'Departure Mono',ui-monospace,monospace;
  font-size:22px;line-height:33px;color:var(--text);
  padding:30px 34px 46px;
}
.case-text p{margin:0 0 22px}
.case-text p:last-child{margin-bottom:0}
.case-text::-webkit-scrollbar{width:14px}
.case-text::-webkit-scrollbar-track{background:var(--sunken);border-left:1px solid var(--hair-soft)}
.case-text::-webkit-scrollbar-thumb{background:var(--thumb);border:1px solid var(--hair)}

/* the hidden holder the slideshow's anchors live in — GLightbox binds to these
   by selector, and a click is synthesised on the one that should open */
.glightbox-src{display:none !important}

/* ---------------------------------------------------------------- narrow */
/* Not a mobile layout — a guarantee that nothing breaks or overlaps before
   the real small-screen pass is designed. The cascade compacts. */
@media (max-width:1100px){
  #volumes{grid-template-columns:repeat(2,minmax(0,1fr))}
  .win.in-flow{min-height:320px}
  .mast-name{font-size:14px;line-height:14px}
  .case-body{flex-direction:column}
  .case-left{flex:0 0 46%;border-right:0;border-bottom:1px solid var(--hair);padding:14px}
  .case-right{flex:1 1 auto}
}
@media (max-width:620px){
  #volumes{grid-template-columns:minmax(0,1fr)}
  .win.in-flow{min-height:260px}
  .doc{padding:18px 16px 30px;font-size:22px}
  .pick.grid{grid-template-columns:repeat(auto-fill,minmax(92px,1fr))}
  .case-text{padding:20px 18px 34px;font-size:22px;line-height:33px}
  .case-left{flex:0 0 52%}
}

/* ----------------------------------------- reduced motion: everything off */
@media (prefers-reduced-motion: reduce){
  *{animation:none !important;transition:none !important}
  #boot{display:none !important}
}
