/* =====================================================================
   📓 archive — his father's locked folder

   Four surfaces: the desktop icon, which spends most of its life locked, and
   the three windows the folder is — the folder itself, `locked out.txt`, and
   his journal.

   ⚠️ THE FILE, THE BODY CLASS AND THE ICON ID STILL SAY `notebook`, AND THAT
   IS DELIBERATE. The folder reads `archive` on the desktop; the gate is still
   `body.notebook-unlocked`, the desktop icon is still `#icon-notebook` and the
   folder art is still `.notebook-folder-art`, because js/apps/morphy.js finds
   the thing Morphy noses open by that id and that class. Renaming either is a
   rename of a dwell target rather than of a label, and it would break the
   biscuit unlock without breaking anything visible. The window ids are the
   ones that moved, and every geometry rule below is written against those.

   HIS JOURNAL IS NOT DRESSED HERE. #archive-journal is laid out by
   js/journal-view.js, which builds the same .journal-page, .journal-entry-*
   and .journal-nav furniture Dash's book gets, so css/journal.css dresses both
   of them. This file adds only the two things that are HIS: the rule down the
   left margin, which is the whole visual difference between the two hands, and
   the cursor on the page that stops. Everything else the two books share is
   now shared rather than copied — the measure and the leading here used to be
   a hand-kept duplicate of the Journal's, with a note telling whoever retuned
   one to go and retune the other.

   Nothing here breaks the retro rules. VT323, hard black borders, flat fills,
   hard offset shadows, discrete state changes.
   ===================================================================== */

/* --- Window geometry ---
   Placed by id HERE rather than in css/main.css, following css/calculator.css,
   which is the precedent that exists because of a real bug: a bare id rule in
   css/main.css outranks every `.window` rule in css/responsive.css, since a
   media query adds no specificity, so a window placed there and not restated
   by id at each breakpoint is still sitting at its desktop offset on a phone.
   The Calculator lost its `=` key behind the dock that way. ALL THREE WINDOWS
   ARE RESTATED BY ID AT BOTH BREAKPOINTS BELOW, so there is nothing for
   css/responsive.css to reach and nothing for it to miss.

   The folder is small because it holds two things, and it is the only one of
   the three that is not a reading window. The two that are take the Journal's
   own 520px measure. They cascade down and right off the folder rather than
   opening on top of it, and both start BELOW the folder's title bar, which is
   what leaves the visitor something to click to get back to it — a folder
   buried by the thing it opened is a folder the second item is unreachable in.

   Two numbers are measured rather than picked. Nothing reaches past x=1000, so
   all three still fit a 1024px desk. And each height is capped at
   `100vh - top - 140`, because the dock's top edge sits at about `100vh - 128`
   and 12px of clearance is what the rest of the OS leaves: the fixed pixel in
   each `min()` is the comfortable size and the calc is the floor that keeps a
   short laptop screen off the dock. His journal's last row is a carousel, so
   that clearance is a control nobody can tap rather than a strip of prose. */
#archive {
  left: 380px;
  top: 110px;
  width: 340px;
  height: 230px;
}

#archive-note {
  left: 450px;
  top: 230px;
  width: 520px;
  height: min(490px, calc(100vh - 370px));
}

#archive-journal {
  left: 480px;
  top: 180px;
  width: 520px;
  height: min(580px, calc(100vh - 320px));
}

/* =====================================================================
   The folder

   A small Finder, because it is a folder and the two things in it are not the
   same kind of object. The listing keeps `.content`'s white, the way Finder's
   does, so it reads as somewhere files are kept rather than as another page.

   The grid and the icon MIRROR .finder-main-container and .finder-icon rather
   than borrowing them — the same call this stylesheet made about the Journal's
   typography, and css/journal.css made about Finder's photo frame: neither app
   can then move the other's furniture. The one thing that is genuinely shared
   is appendFinderIconLabel(), because "a filename may never grow a character
   it does not have" is supposed to have exactly one implementation.
   ===================================================================== */

.archive-grid {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  align-items: flex-start;
  gap: 20px;
  padding: 5px;
}

.archive-icon {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 80px;
  padding: 6px 2px;
  text-align: center;
  cursor: pointer;
  user-select: none;
}

/* The retro selected state, not a modern blue. */
.archive-icon.selected {
  background: #000;
  color: #fff;
}

/* The shared token rather than a number, so the phone override in
   css/responsive.css takes this down with every other icon in the OS. Sized
   here rather than by joining the list in css/main.css, which is shared chrome
   and not the place for one app's icon. */
.archive-icon img {
  width: var(--file-icon-size);
  height: var(--file-icon-size);
  object-fit: contain;
  pointer-events: none;
}

/* hyphens: manual, i.e. only where a soft hyphen was actually typed. `auto` was
   inventing its own in Finder and in the desktop's own labels, and the one
   filename the whole endgame turns on came out as `in-staller.d-mg`. There is
   a filename in this folder too. overflow-wrap still breaks a label too long
   for the 80px column — it just breaks it without adding a character. */
.archive-icon span {
  display: block;
  margin-top: 6px;
  font-size: 14px;
  word-break: normal;
  overflow-wrap: anywhere;
  hyphens: manual;
}

.archive-icon.selected span {
  color: inherit;
}

/* =====================================================================
   locked out.txt

   Its own window, the way ReadMe.txt gets one. A typed sheet rather than
   handwriting, so it sits a point tighter than his diary prose next door and
   the heading loses its sentence case — but it keeps the rule down the left
   margin, because it is the same hand.
   ===================================================================== */

/* Scoped by id for the reason css/journal.css records: the shared
   `.window .content` rule in css/main.css is a two-class selector and would
   otherwise keep its white background under a bare class here. Both desktop
   themes still win, because they set this with !important. */
#archive-note .content,
#archive-journal .content {
  display: flex;
  flex-direction: column;
  padding: 0;
  background: var(--panel);
}

/* The one scrolling region, so the window never changes size.
   scrollbar-gutter keeps the bar's width reserved on platforms that take space
   for one. */
.archive-scroll {
  flex: 1 1 auto;
  min-height: 0;
  padding: 16px;
  overflow-y: auto;
  scrollbar-gutter: stable;
}

/* The same drawn scrollbar .journal-pages and .msg-transcript use, mirrored for
   the same reason the type is. macOS hides its overlay scrollbar until you
   already scroll, which is how a sheet that continues below the fold ends up
   looking like a sheet that stops. */
.archive-scroll::-webkit-scrollbar {
  width: 13px;
}
.archive-scroll::-webkit-scrollbar-track {
  border: 2px solid #000;
  background: #ececec;
}
.archive-scroll::-webkit-scrollbar-thumb {
  border: 2px solid #000;
  background: #9a9a9a;
}

/* `safe center` is what makes the centring survive a sheet that grows past the
   region; plain `center` would push the first line out of reach above the
   scroll origin. Browsers that do not know the keyword drop the declaration and
   fall back to the top, which is what the overflow case wants anyway.

   The margin rule is in currentColor so it arrives in whatever the theme has
   painted the panel, and there is nothing to keep in step if a theme's green
   is ever retuned. */
.archive-note-page {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  justify-content: safe center;
  gap: 14px;
  max-width: 560px;
  margin-inline: auto;
  border-left: 3px solid currentColor;
  padding-left: 16px;
}

.archive-note-head {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-bottom: 2px;
}

.archive-note-title {
  margin: 0;
  font-family: "VT323", monospace;
  font-size: 25px;
  line-height: 1.1;
  letter-spacing: 1px;
}

/* The date and the year-count carry more here than a job tag does on Dash's
   pages — between them they are how a reader works out who is writing and when
   — so they recede less than the 0.6 the Journal's meta line takes. */
.archive-note-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 2px 14px;
  font-family: "VT323", monospace;
  font-size: 16px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  opacity: 0.75;
}

.archive-note-date {
  flex-shrink: 0;
}

.archive-note-tag {
  text-align: right;
}

.archive-note-body {
  margin: 0;
  font-family: "VT323", monospace;
  font-size: 20px;
  line-height: 1.45;
}

/* =====================================================================
   His journal

   Two rules, and both of them are his. Everything else on this window —
   the page, the head, the meta line, the prose, the carousel — is
   css/journal.css doing the same job it does for Dash's book, because
   js/journal-view.js builds both from the same code. His pages carry no
   photograph, so every one of them takes .journal-page.is-textonly, which is
   where the wider measure and the extra leading now come from; this file used
   to restate those values by hand.
   ===================================================================== */

/* A second hand, in the margin, in currentColor so it arrives in whatever the
   theme has painted the panel. It is the whole visual difference between this
   book and Dash's, and it is scoped to this window so it can never reach his. */
#archive-journal .journal-page {
  border-left: 3px solid currentColor;
  padding-left: 16px;
}

/* --- The page that stops ---
   His last entry runs out mid-sentence. Left bare, a paragraph ending without a
   full stop reads as a typo; this is what makes it read as an interruption.

   A drawn box rather than a block character, because VT323 is a pixel font and
   a glyph it happens not to carry would render as tofu. Static, with no blink:
   the OS keeps looping motion out of ordinary surfaces, and a cursor left
   sitting where somebody stopped typing is more unsettling than one that is
   obviously alive.

   :last-child rather than a class on the paragraph, so it lands on whatever the
   final paragraph turns out to be if that page is ever re-cut. Nothing in Dash's
   book carries `unfinished`, and the window scope means nothing in it could. */
#archive-journal .journal-page.is-unfinished .journal-entry-body:last-child::after {
  content: "";
  display: inline-block;
  width: 0.45em;
  height: 0.8em;
  margin-left: 5px;
  background: currentColor;
  vertical-align: baseline;
}

/* =====================================================================
   The desktop icon, and the padlock

   The icon is an ordinary .desktop-icon wearing the OS's own folderIcon.webp,
   so it drags, selects and mirrors into Finder for free. Locked is drawn rather
   than swapped, because a stylesheet cannot change an <img src> and this folder
   spends most of a play-through locked.

   Two states and one selector each:
     - locked   the artwork goes flat and cold, and a padlock is drawn over it
     - unlocked body.notebook-unlocked is on, so both rules stop applying

   THE CLASS USED TO BE `matrix-theme` AND IS NOT ANY MORE. The dog opens this
   folder now, not the theme — see the header of js/apps/notebook.js. Only
   applyNotebookUnlocked() writes the class, and the MutationObserver in that
   file strips it again the moment PURGE takes the desktop, so the padlock can
   never be missing from an icon the gate is refusing.

   The padlock is a ::before on the CONTAINER, not on the image, because an
   <img> cannot carry a pseudo-element. On the desktop that container is
   #icon-notebook. In Finder it is whatever div createFinderIcon() built, which
   is why the mirror is reached through :has() on the image class the desktop
   copy hands down — renderFinderContent("desktop") copies an icon's image
   classes but not its container's, and adding container-class mirroring to
   Finder for one app's benefit would be the wrong place to fix this.
   ===================================================================== */

/* Desaturated and dimmed rather than hidden. The folder is meant to be a thing
   you can see and cannot have. */
body:not(.notebook-unlocked) .notebook-folder-art {
  filter: grayscale(100%) brightness(0.62) contrast(0.9);
}

/* Only the Finder mirror needs this. `.desktop-icon` in css/main.css is already
   `position: absolute`, which is just as good a containing block for the
   padlock's absolutely-positioned ::before — and forcing #icon-notebook to
   `relative` drops it out of absolute positioning into normal flow, which
   pushes every element after it down the page and takes the menu bar with it. */
body:not(.notebook-unlocked) .finder-icon:has(.notebook-folder-art) {
  position: relative;
}

/* A padlock drawn in two boxes: a shackle and a body. No glyph, because VT323
   is a pixel font and 🔒 would either render as tofu or drag in a colour emoji
   that belongs to no part of this OS's palette.

   Sizes are in px rather than em so the lock is the same size on the 60px
   desktop icon and the 40px phone one — it is a badge on the artwork, not part
   of it. */
body:not(.notebook-unlocked) #icon-notebook::before,
body:not(.notebook-unlocked) .finder-icon:has(.notebook-folder-art)::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 9px;
  height: 9px;
  margin: -13px 0 0 -6px;
  border: 2px solid #f4f4f4;
  border-bottom: 0;
  border-radius: 5px 5px 0 0;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.85);
  pointer-events: none;
  z-index: 2;
}

body:not(.notebook-unlocked) #icon-notebook::after,
body:not(.notebook-unlocked) .finder-icon:has(.notebook-folder-art)::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 16px;
  height: 12px;
  margin: -5px 0 0 -8px;
  border: 2px solid #000;
  background: #f4f4f4;
  pointer-events: none;
  z-index: 2;
}

/* The selected state paints the container black, and a white padlock body on
   black still reads. Nothing to do but keep the ring visible. */
body:not(.notebook-unlocked) #icon-notebook.selected::after {
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.6);
}

/* =====================================================================
   The biscuit

   Its own rule rather than the shared icon box, and the arithmetic is the
   reason. The art is a 32x32 pixel grid shipped at 8x (256x256), and one art
   pixel has to land on a whole number of device pixels or a one-pixel outline
   comes out with some segments twice the thickness of others. The shared boxes
   are 60px and 40px, neither of which divides 32: they would put an art pixel
   on 1.875 and 1.25 CSS pixels. 64 and 32 are the nearest whole multiples, 2x
   and 1x of the grid, and every ratio above them is whole as well.

   That is the same rule #morphy-house follows for the same reason, and it is
   why `pixelated` is right here on what is nominally a downscale — the file is
   flat 8x8 blocks, so dropping pixels out of it is exact. **If the art is ever
   replaced, measure its grid rather than assuming this one.**

   It deliberately carries no `finder-thumb`. That class is for pictures — it
   crops square, frames them and puts a white plate behind them — and this is an
   object, like installer.webp and rootbeer.webp beside it, which do not carry
   it either. A white plate would also take the transparency off a biscuit.
   ===================================================================== */
.finder-icon img.finder-treat-art {
  width: 64px;
  height: 64px;
  image-rendering: pixelated;
}

/* =====================================================================
   Leading him somewhere — the biscuit's dwell, and the folder's

   Both reuse Morphy's House exactly: the target is armed by the pointer or by
   a press latching it, he has to walk over and stand there, and both have to
   hold for the dwell while a meter counts it out where the visitor can see it.
   The values below are the house's own, so all three feel like one mechanic —
   `#morphy-house.filling .morphy-house-meter-fill` in css/trash.css is the
   original and HOUSE_DWELL in js/apps/morphy.js has to stay in step with both.

   ⚠️ THE METER IS A BODY CHILD, NOT A CHILD OF THE TARGET, and that is
   load-bearing rather than lazy. The biscuit lives inside the Finder window,
   `.window` is `overflow: hidden`, and a meter drawn inside an icon near the
   window's edge would be clipped in half. It is the same call
   #music-minimize-hint makes for the same reason: the cost is that
   js/apps/morphy.js has to place it against the target's own rect, and the
   benefit is that it is never cropped and the icon never moves to make room.

   z-index 8898 puts it above every window and the dock, and one below the paw
   prints at 8899 — so he walks over his own meter the way he walks in front of
   his house.
   ===================================================================== */
.morphy-dwell-meter {
  position: fixed;
  z-index: 8898;
  width: 96px;
  height: 12px;
  border: 3px solid #000;
  background: #fffdf2;
  box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.9);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
}
.morphy-dwell-meter.armed {
  opacity: 1;
  visibility: visible;
}
.morphy-dwell-meter-fill {
  display: block;
  width: 0;
  height: 100%;
  background: #000;
}
/* Stepped rather than smooth, so it reads as a chunky retro gauge, and the snap
   back to zero on cancel is deliberately untransitioned. */
.morphy-dwell-meter.filling .morphy-dwell-meter-fill {
  width: 100%;
  transition: width 1400ms steps(8, end);
}

/* Armed, by pointing at it or by pressing it open. A flat brightening and the
   OS's own hard shadow — no scale hover, the same rule #morphy-house.armed
   follows. */
.morphy-dwell-armed img {
  filter: brightness(1.12) drop-shadow(4px 4px 0 rgba(0, 0, 0, 0.55));
}
/* The folder is armed while it is still wearing its padlock, so the dimming
   above it has to be lifted or the "he can do this now" state is invisible
   under `grayscale(100%) brightness(0.62)`. */
body:not(.notebook-unlocked) .morphy-dwell-armed .notebook-folder-art {
  filter: brightness(1.12) drop-shadow(4px 4px 0 rgba(0, 0, 0, 0.55));
}

/* --- Tablet ---
   All three restated by id for the reason the geometry block above records.

   ⚠️ THE READING WINDOWS START ONE TITLE BAR BELOW THE FOLDER, and that 46px
   is functional rather than decorative. There is no room to cascade sideways
   at this width, so the folder is full width under whichever of the two is on
   top; landing them on the same `top` buried its title bar as well, and with
   the title bar went the only way back to the folder — which made the SECOND
   item in it unreachable as soon as the first was opened. This was found at
   320px with a real tap, not by measuring. Keep the offset above 36px. */
@media (max-width: 768px) {
  #archive {
    left: 7.5%;
    top: 60px;
    width: 85%;
    height: 240px;
  }

  #archive-note,
  #archive-journal {
    left: 7.5%;
    top: 106px;
    width: 85%;
    /* At 768x1024 the dock's top edge is y=924: this lands the bottom edge 14px
       clear of it. Measured rather than copied from the neighbouring windows,
       which use 150 and sit 10px behind it. */
    height: calc(100vh - 220px);
  }
}

/* --- Phone ---
   320x568 is the floor the OS supports. */
@media (max-width: 600px) {
  #archive {
    left: 3%;
    top: 50px;
    width: 94%;
    height: 200px;
  }

  #archive-note,
  #archive-journal {
    left: 3%;
    /* One title bar below the folder, for the reason recorded at the tablet
       block above: this is what leaves something to tap to get back to it. */
    top: 92px;
    width: 94%;
    /* Measured at 320x568, where the dock's top edge is y=464: top 92 plus
       this height lands the bottom edge 12px clear of it. The 130px the other
       windows at this breakpoint use puts them 24px behind the dock, which
       costs nothing where the whole window scrolls — but his journal's last
       row is the carousel, and a PREV/NEXT nobody can tap is the same shape of
       bug as the Calculator's `=` key. Measure this again if either window
       grows a control at the foot. */
    height: calc(100vh - 208px);
  }

  .archive-grid {
    gap: 14px;
  }

  .archive-scroll {
    padding: 12px;
  }

  /* The region's padding drops to 12px, so the rule and its indent take the
     same step down and the measure keeps its width. */
  .archive-note-page {
    padding-left: 12px;
  }

  #archive-journal .journal-page {
    padding-left: 12px;
  }

  .archive-note-body {
    font-size: 18px;
  }

  /* At this width the date and the year-count cannot share a line without one
     of them wrapping mid-word — the same fix .journal-entry-meta takes. */
  .archive-note-meta {
    flex-direction: column;
    align-items: flex-start;
  }

  .archive-note-tag {
    text-align: left;
  }

  /* 1x the grid. Down from 64 rather than from the 40px the icons around it
     take, because 40 is not a multiple of 32 — see the block above. A biscuit
     reading a little smaller than the folders beside it is also the right
     answer for what it is. */
  .finder-icon img.finder-treat-art {
    width: 32px;
    height: 32px;
  }
}
