/* ==========================================================================
   FauxOS — main stylesheet
   --------------------------------------------------------------------------
   The base layer: reset, the desktop the window sits on, the workspace grid,
   and the state machines that decide what is showing.

   Load order — later files use variables defined earlier:

     fonts.css      five faces, four pairings, all SIL OFL
     themes.css     palettes, brightness, contrast, desktop ground
     patterns.css   thirteen tiles, all scaled from one size variable
     main.css       THIS FILE — reset, desktop, layout, state machines
     buttons.css    the four click behaviours
     window.css     frame, title bar, menu bar, panels, status bar
     panels.css     category tree, information box, outline
     content.css    article body, headings, plates
     intro.css      title screen
     crt.css        screen effect

   HOUSE STYLE
     Blocky. Interface elements are rectangles with right angles, bevels are
     one or two pixels, shadows are hard rectangular offsets — never blurred,
     never diagonal. Two deliberate exceptions: the window frame and the
     loading bar carry a small radius, and desktop patterns behind the window
     may use diagonals. Everything else keeps its corners.

   CONTENTS
     01  reset
     02  the desktop
     03  hidden state
     04  workspace grid
     05  PAGES — which page of which article is open
     06  OUTLINE — marking where you are inside the article
     07  INFORMATION BOX — what the pointer is over
     08  keyboard focus
     09  desktop-only notice
   ========================================================================== */


/* ==========================================================================
   01  RESET
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html, body {
  height: 100%;
  overflow: hidden;              /* nothing on this site ever scrolls */
}

/* HOW BIG THE INTERFACE IS DRAWN, as a plain multiplier of the design size.

   The window is 1280 x 872 and stays 1280 x 872 in every length it is built
   from; this is the one number that changes, and the script rewrites it on
   load and on every resize. Declaring it here rather than only in the script
   means the site is still laid out correctly for the instant before the
   script runs, and stays correct if it never does.

   1 is the design size, not a ceiling: it goes below 1 on a display with less
   room than the design wants and above 1 on one with more, so the interface
   fills the screen it is given at every resolution instead of only at the
   ones that happen to match. */
html { --fit: 1; }

h1, h2, h3, p, ul, figure, figcaption { margin: 0; padding: 0; }
ul { list-style: none; }
label { cursor: pointer; }


/* ==========================================================================
   02  THE DESKTOP
   ========================================================================== */

body {
  margin: 0;
  display: grid;
  place-items: center;

  font-family: var(--f-body);
  font-size: var(--f-size);
  line-height: var(--f-line);
  color: var(--ink);

  background-color: var(--desk);

  /* Smoothing is decided per face in fonts.css — a pixel grid wants it off,
     an outline design needs it on. Setting it here applied one answer to
     every face and was wrecking the outline ones. */
  text-rendering: optimizeSpeed;
  -webkit-text-size-adjust: none;

  /* the two bevels every control is built from */
  --bevel-up:   inset  1px  1px 0 0 var(--edge-lt),
                inset -1px -1px 0 0 var(--edge-dk);
  --bevel-down: inset  1px  1px 0 0 var(--edge-dk),
                inset -1px -1px 0 0 var(--edge-lt);
}


/* The pattern rides on its own layer so it can be turned. Rotating the body
   background is not possible; rotating a layer is.

   The layer is oversized so its corners stay covered as it turns — but that
   oversizing is exactly what broke Fill screen and Whole image. `cover` and
   `contain` resolve against the box they are painted into, and `center`
   centres in that box, so an uploaded photo was being fitted to an area
   twice the screen and then shown from the middle. A picture does not need
   to rotate, so --pat-inset drops to 0 for one and the fit means what it
   says. */
body::before {
  content: "";
  position: fixed;
  /* A CENTRED SQUARE, NOT AN OVERSIZED VIEWPORT.

     This was inset:-50%, a box twice the viewport in each direction. Rotate a
     2w by 2h box about its centre and the area it is guaranteed to cover is a
     circle of radius min(w,h) — the shorter side. On 4:3 that clears the
     viewport's half-diagonal; on 16:9 it falls a couple of percent short, and
     on anything wider it is nowhere near. So at some angles the corners of the
     screen fell outside the pattern and you could see the layer's own edge cut
     across them, worse the wider the viewport got.

     A square has no short side. Rotated about its centre it always covers a
     circle of radius S/2, and the worst-case half-diagonal of any viewport is
     70.8vmax, so 160vmax clears every aspect ratio with room to spare. An
     uploaded photograph overrides both dimensions to the viewport's own, since
     Fill and Whole have to resolve against the screen rather than the layer. */
  top: 50%;
  left: 50%;
  width: var(--pat-w, 160vmax);
  height: var(--pat-h, 160vmax);
  z-index: -1;
  pointer-events: none;
  background-image: var(--p-active, none);
  background-size: var(--ps-active, auto);
  background-position: var(--pp-active, 0 0);
  background-repeat: var(--pr-active, repeat);
  /* Nearest-neighbour is right for a pixel tile and wrong for a photograph.
     It used to be set here unconditionally, so an uploaded picture was scaled
     without interpolation — blocky at rest, and worse mid-pinch, when the
     scale factor passes through every value between two zoom levels and each
     one re-aliases the edges. The script switches it to auto when what is
     loaded is a picture rather than a tile. */
  image-rendering: var(--pat-render, pixelated);
  transform: translate(-50%, -50%) rotate(var(--pat-rot, 0deg));
}


/* ==========================================================================
   03  HIDDEN STATE
   Every input the site runs on. Hidden from view but kept in the
   accessibility tree and reachable from the keyboard.
   ========================================================================== */

.state {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}


/* ==========================================================================
   04  WORKSPACE GRID
   ========================================================================== */

.workspace {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 256px minmax(0, 1fr) 256px;
  gap: 2px;
  background: var(--ink);        /* shows through the gaps as rules */
}


/* ==========================================================================
   05  PAGES
   --------------------------------------------------------------------------
   Page ids read article-then-page: a1 is the first page of article A.
   A page drives the .pane in the middle and the .sbar at the bottom; the
   article it belongs to drives the outline and the row lit in the tree.

   To add a page: add its radio, give its .pane and .sbar the same data-pg,
   and add it to its article's lists below.
   ========================================================================== */

[data-pg]  { display: none; }
[data-art] { display: none; }    /* only the open article's outline shows */

body:has(#pg-a1:checked) [data-pg="a1"] { display: flex; }
body:has(#pg-a2:checked) [data-pg="a2"] { display: flex; }
body:has(#pg-a3:checked) [data-pg="a3"] { display: flex; }
body:has(#pg-a4:checked) [data-pg="a4"] { display: flex; }
body:has(#pg-b1:checked) [data-pg="b1"] { display: flex; }
body:has(#pg-b2:checked) [data-pg="b2"] { display: flex; }
body:has(#pg-b3:checked) [data-pg="b3"] { display: flex; }
body:has(#pg-b4:checked) [data-pg="b4"] { display: flex; }
body:has(#pg-c1:checked) [data-pg="c1"] { display: flex; }
body:has(#pg-c2:checked) [data-pg="c2"] { display: flex; }
body:has(#pg-c3:checked) [data-pg="c3"] { display: flex; }
body:has(#pg-d1:checked) [data-pg="d1"] { display: flex; }
body:has(#pg-d2:checked) [data-pg="d2"] { display: flex; }
body:has(#pg-e1:checked) [data-pg="e1"] { display: flex; }
body:has(#pg-e2:checked) [data-pg="e2"] { display: flex; }

body:has(#pg-a1:checked, #pg-a2:checked, #pg-a3:checked, #pg-a4:checked) [data-art="a"],
body:has(#pg-b1:checked, #pg-b2:checked, #pg-b3:checked, #pg-b4:checked) [data-art="b"],
body:has(#pg-c1:checked, #pg-c2:checked, #pg-c3:checked) [data-art="c"],
body:has(#pg-d1:checked, #pg-d2:checked)                 [data-art="d"],
body:has(#pg-e1:checked, #pg-e2:checked)                 [data-art="e"] {
  display: flex;
}

body:has(#pg-a1:checked, #pg-a2:checked, #pg-a3:checked, #pg-a4:checked) [data-nav="a"],
body:has(#pg-b1:checked, #pg-b2:checked, #pg-b3:checked, #pg-b4:checked) [data-nav="b"],
body:has(#pg-c1:checked, #pg-c2:checked, #pg-c3:checked) [data-nav="c"],
body:has(#pg-d1:checked, #pg-d2:checked)                 [data-nav="d"],
body:has(#pg-e1:checked, #pg-e2:checked)                 [data-nav="e"] {
  color: var(--sel-ink);
  background: var(--sel);
}

/* the category holding the open article draws itself open */
body:has(#pg-a1:checked, #pg-a2:checked, #pg-a3:checked, #pg-a4:checked,
         #pg-b1:checked, #pg-b2:checked, #pg-b3:checked, #pg-b4:checked) [data-cat="1"],
body:has(#pg-c1:checked, #pg-c2:checked, #pg-c3:checked) [data-cat="2"],
body:has(#pg-d1:checked, #pg-d2:checked)                 [data-cat="3"],
body:has(#pg-e1:checked, #pg-e2:checked)                 [data-cat="4"] {
  color: var(--link);
}
body:has(#pg-a1:checked, #pg-a2:checked, #pg-a3:checked, #pg-a4:checked,
         #pg-b1:checked, #pg-b2:checked, #pg-b3:checked, #pg-b4:checked) [data-cat="1"] .ico-cat,
body:has(#pg-c1:checked, #pg-c2:checked, #pg-c3:checked) [data-cat="2"] .ico-cat,
body:has(#pg-d1:checked, #pg-d2:checked)                 [data-cat="3"] .ico-cat,
body:has(#pg-e1:checked, #pg-e2:checked)                 [data-cat="4"] .ico-cat {
  clip-path: polygon(0 0, 6px 0, 6px 2px, 14px 2px, 14px 11px, 0 11px,
                     0 4px, 2px 4px, 2px 9px, 12px 9px, 12px 4px, 0 4px);
}


/* ==========================================================================
   06  OUTLINE
   The chapter you are reading marks itself and stops being a link, since it
   would only lead back to the page you are on.
   ========================================================================== */

body:has(#pg-a1:checked) .ol-link[data-ol="a1"],
body:has(#pg-a2:checked) .ol-link[data-ol="a2"],
body:has(#pg-a3:checked) .ol-link[data-ol="a3"],
body:has(#pg-a4:checked) .ol-link[data-ol="a4"],
body:has(#pg-b1:checked) .ol-link[data-ol="b1"],
body:has(#pg-b2:checked) .ol-link[data-ol="b2"],
body:has(#pg-b3:checked) .ol-link[data-ol="b3"],
body:has(#pg-b4:checked) .ol-link[data-ol="b4"],
body:has(#pg-c1:checked) .ol-link[data-ol="c1"],
body:has(#pg-c2:checked) .ol-link[data-ol="c2"],
body:has(#pg-c3:checked) .ol-link[data-ol="c3"],
body:has(#pg-d1:checked) .ol-link[data-ol="d1"],
body:has(#pg-d2:checked) .ol-link[data-ol="d2"],
body:has(#pg-e1:checked) .ol-link[data-ol="e1"],
body:has(#pg-e2:checked) .ol-link[data-ol="e2"] {
  pointer-events: none;
  color: var(--sel-ink);
  background: var(--sel);
}
body:has(#pg-a1:checked) .ol-link[data-ol="a1"] .n,
body:has(#pg-a2:checked) .ol-link[data-ol="a2"] .n,
body:has(#pg-a3:checked) .ol-link[data-ol="a3"] .n,
body:has(#pg-a4:checked) .ol-link[data-ol="a4"] .n,
body:has(#pg-b1:checked) .ol-link[data-ol="b1"] .n,
body:has(#pg-b2:checked) .ol-link[data-ol="b2"] .n,
body:has(#pg-b3:checked) .ol-link[data-ol="b3"] .n,
body:has(#pg-b4:checked) .ol-link[data-ol="b4"] .n,
body:has(#pg-c1:checked) .ol-link[data-ol="c1"] .n,
body:has(#pg-c2:checked) .ol-link[data-ol="c2"] .n,
body:has(#pg-c3:checked) .ol-link[data-ol="c3"] .n,
body:has(#pg-d1:checked) .ol-link[data-ol="d1"] .n,
body:has(#pg-d2:checked) .ol-link[data-ol="d2"] .n,
body:has(#pg-e1:checked) .ol-link[data-ol="e1"] .n,
body:has(#pg-e2:checked) .ol-link[data-ol="e2"] .n { color: var(--sel-ink); }


/* ==========================================================================
   07  INFORMATION BOX
   Anything worth describing carries data-info="key"; the box holds one
   paragraph per key, marked data-for="key".

   The subject of these rules is .window rather than <body> on purpose. Every
   data-info element lives inside the window, and a :has() whose subject is
   <body> makes the browser re-evaluate the whole document on every pointer
   move across a control. Scoping it keeps that work inside the window.
   ========================================================================== */

.window:has([data-info]:hover) .tip-default { display: none; }

/* TIP-LIST-START */
.window:has([data-info="w-close"]:hover) .tip[data-for="w-close"],
.window:has([data-info="w-min"]:hover) .tip[data-for="w-min"],
.window:has([data-info="m-intro"]:hover) .tip[data-for="m-intro"],
.window:has([data-info="m-sound"]:hover) .tip[data-for="m-sound"],
.window:has([data-info="m-desk"]:hover) .tip[data-for="m-desk"],
.window:has([data-info="m-theme"]:hover) .tip[data-for="m-theme"],
.window:has([data-info="m-screen"]:hover) .tip[data-for="m-screen"],
.window:has([data-info="m-font"]:hover) .tip[data-for="m-font"],
.window:has([data-info="m-mode"]:hover) .tip[data-for="m-mode"],
.window:has([data-info="fold-cat"]:hover) .tip[data-for="fold-cat"],
.window:has([data-info="cat-1"]:hover) .tip[data-for="cat-1"],
.window:has([data-info="art-a"]:hover) .tip[data-for="art-a"],
.window:has([data-info="art-b"]:hover) .tip[data-for="art-b"],
.window:has([data-info="cat-2"]:hover) .tip[data-for="cat-2"],
.window:has([data-info="art-c"]:hover) .tip[data-for="art-c"],
.window:has([data-info="cat-3"]:hover) .tip[data-for="cat-3"],
.window:has([data-info="art-d"]:hover) .tip[data-for="art-d"],
.window:has([data-info="cat-4"]:hover) .tip[data-for="cat-4"],
.window:has([data-info="art-e"]:hover) .tip[data-for="art-e"],
.window:has([data-info="outline"]:hover) .tip[data-for="outline"],
.window:has([data-info="fold-ol"]:hover) .tip[data-for="fold-ol"],
.window:has([data-info="nav-next"]:hover) .tip[data-for="nav-next"],
.window:has([data-info="nav-prev"]:hover) .tip[data-for="nav-prev"]
/* TIP-LIST-END */
{
  display: block;
}


/* ==========================================================================
   08  KEYBOARD FOCUS
   ========================================================================== */

body:has(#pg-a1:focus-visible) [data-nav="a"],
body:has(#pg-b1:focus-visible) [data-nav="b"],
body:has(#pg-c1:focus-visible) [data-nav="c"],
body:has(#pg-d1:focus-visible) [data-nav="d"],
body:has(#pg-e1:focus-visible) [data-nav="e"],
/* Every menu option, listed. This was hand-written and stopped at th-5 and
   fn-4 — from when there were five schemes and four faces — so thirty-four
   schemes and two faces took keyboard focus with no outline to show for it,
   and #fn-2 was still listed after that face was dropped.

   It has to be a list. The inputs live in .state, nowhere near the labels
   that point at them, and CSS cannot relate #th-7:focus-visible to
   [for="th-7"] without naming both. The list below is generated from the
   markup rather than typed, so it covers every option there is; it gzips to
   almost nothing because every line is the same shape.

   Generated by build_focus.py — rerun it if the menus change. */
/* FOCUS-LIST-START */
body:has(#intro-off:focus-visible) .mopt[for="intro-off"],
body:has(#isp-1:focus-visible) .mopt[for="isp-1"],
body:has(#isp-2:focus-visible) .mopt[for="isp-2"],
body:has(#isp-3:focus-visible) .mopt[for="isp-3"],
body:has(#bsp-1:focus-visible) .mopt[for="bsp-1"],
body:has(#bsp-2:focus-visible) .mopt[for="bsp-2"],
body:has(#bsp-3:focus-visible) .mopt[for="bsp-3"],
body:has(#snd-boot:focus-visible) .mopt[for="snd-boot"],
body:has(#mute:focus-visible) .mopt[for="mute"],
body:has(#snd-hover:focus-visible) .mopt[for="snd-hover"],
body:has(#snd-click:focus-visible) .mopt[for="snd-click"],
body:has(#snd-page:focus-visible) .mopt[for="snd-page"],
body:has(#kit-mech:focus-visible) .mopt[for="kit-mech"],
body:has(#kit-soft:focus-visible) .mopt[for="kit-soft"],
body:has(#kit-glass:focus-visible) .mopt[for="kit-glass"],
body:has(#kit-metal:focus-visible) .mopt[for="kit-metal"],
body:has(#kit-paper:focus-visible) .mopt[for="kit-paper"],
body:has(#kit-custom:focus-visible) .mopt[for="kit-custom"],
body:has(#hk-mech:focus-visible) .mopt[for="hk-mech"],
body:has(#hk-soft:focus-visible) .mopt[for="hk-soft"],
body:has(#hk-glass:focus-visible) .mopt[for="hk-glass"],
body:has(#hk-metal:focus-visible) .mopt[for="hk-metal"],
body:has(#hk-paper:focus-visible) .mopt[for="hk-paper"],
body:has(#ck-mech:focus-visible) .mopt[for="ck-mech"],
body:has(#ck-soft:focus-visible) .mopt[for="ck-soft"],
body:has(#ck-glass:focus-visible) .mopt[for="ck-glass"],
body:has(#ck-metal:focus-visible) .mopt[for="ck-metal"],
body:has(#ck-paper:focus-visible) .mopt[for="ck-paper"],
body:has(#pk-mech:focus-visible) .mopt[for="pk-mech"],
body:has(#pk-soft:focus-visible) .mopt[for="pk-soft"],
body:has(#pk-glass:focus-visible) .mopt[for="pk-glass"],
body:has(#pk-metal:focus-visible) .mopt[for="pk-metal"],
body:has(#pk-paper:focus-visible) .mopt[for="pk-paper"],
body:has(#pat-1:focus-visible) .mopt[for="pat-1"],
body:has(#pat-2:focus-visible) .mopt[for="pat-2"],
body:has(#pat-3:focus-visible) .mopt[for="pat-3"],
body:has(#pat-4:focus-visible) .mopt[for="pat-4"],
body:has(#pat-5:focus-visible) .mopt[for="pat-5"],
body:has(#pat-6:focus-visible) .mopt[for="pat-6"],
body:has(#pat-7:focus-visible) .mopt[for="pat-7"],
body:has(#pat-8:focus-visible) .mopt[for="pat-8"],
body:has(#pat-9:focus-visible) .mopt[for="pat-9"],
body:has(#pat-10:focus-visible) .mopt[for="pat-10"],
body:has(#pat-11:focus-visible) .mopt[for="pat-11"],
body:has(#pat-12:focus-visible) .mopt[for="pat-12"],
body:has(#pat-13:focus-visible) .mopt[for="pat-13"],
body:has(#pat-14:focus-visible) .mopt[for="pat-14"],
body:has(#bg-0:focus-visible) .mopt[for="bg-0"],
body:has(#bg-file:focus-visible) .mopt[for="bg-file"],
body:has(#fit-cover:focus-visible) .mopt[for="fit-cover"],
body:has(#fit-contain:focus-visible) .mopt[for="fit-contain"],
body:has(#fit-tile:focus-visible) .mopt[for="fit-tile"],
body:has(#th-1:focus-visible) .mopt[for="th-1"],
body:has(#th-2:focus-visible) .mopt[for="th-2"],
body:has(#th-3:focus-visible) .mopt[for="th-3"],
body:has(#th-4:focus-visible) .mopt[for="th-4"],
body:has(#th-5:focus-visible) .mopt[for="th-5"],
body:has(#th-6:focus-visible) .mopt[for="th-6"],
body:has(#th-7:focus-visible) .mopt[for="th-7"],
body:has(#th-8:focus-visible) .mopt[for="th-8"],
body:has(#th-9:focus-visible) .mopt[for="th-9"],
body:has(#th-10:focus-visible) .mopt[for="th-10"],
body:has(#th-11:focus-visible) .mopt[for="th-11"],
body:has(#th-12:focus-visible) .mopt[for="th-12"],
body:has(#th-13:focus-visible) .mopt[for="th-13"],
body:has(#th-14:focus-visible) .mopt[for="th-14"],
body:has(#th-15:focus-visible) .mopt[for="th-15"],
body:has(#th-16:focus-visible) .mopt[for="th-16"],
body:has(#th-17:focus-visible) .mopt[for="th-17"],
body:has(#th-18:focus-visible) .mopt[for="th-18"],
body:has(#th-19:focus-visible) .mopt[for="th-19"],
body:has(#th-20:focus-visible) .mopt[for="th-20"],
body:has(#th-21:focus-visible) .mopt[for="th-21"],
body:has(#th-22:focus-visible) .mopt[for="th-22"],
body:has(#th-23:focus-visible) .mopt[for="th-23"],
body:has(#th-24:focus-visible) .mopt[for="th-24"],
body:has(#th-25:focus-visible) .mopt[for="th-25"],
body:has(#th-26:focus-visible) .mopt[for="th-26"],
body:has(#th-27:focus-visible) .mopt[for="th-27"],
body:has(#th-28:focus-visible) .mopt[for="th-28"],
body:has(#th-29:focus-visible) .mopt[for="th-29"],
body:has(#th-30:focus-visible) .mopt[for="th-30"],
body:has(#th-31:focus-visible) .mopt[for="th-31"],
body:has(#th-32:focus-visible) .mopt[for="th-32"],
body:has(#th-33:focus-visible) .mopt[for="th-33"],
body:has(#th-34:focus-visible) .mopt[for="th-34"],
body:has(#th-35:focus-visible) .mopt[for="th-35"],
body:has(#th-36:focus-visible) .mopt[for="th-36"],
body:has(#th-37:focus-visible) .mopt[for="th-37"],
body:has(#th-38:focus-visible) .mopt[for="th-38"],
body:has(#th-39:focus-visible) .mopt[for="th-39"],
body:has(#con-1:focus-visible) .mopt[for="con-1"],
body:has(#con-2:focus-visible) .mopt[for="con-2"],
body:has(#bs-1:focus-visible) .mopt[for="bs-1"],
body:has(#bs-2:focus-visible) .mopt[for="bs-2"],
body:has(#bs-3:focus-visible) .mopt[for="bs-3"],
body:has(#bs-4:focus-visible) .mopt[for="bs-4"],
body:has(#bs-5:focus-visible) .mopt[for="bs-5"],
body:has(#crt-0:focus-visible) .mopt[for="crt-0"],
body:has(#crt-1:focus-visible) .mopt[for="crt-1"],
body:has(#crt-2:focus-visible) .mopt[for="crt-2"],
body:has(#crv-0:focus-visible) .mopt[for="crv-0"],
body:has(#crv-sq:focus-visible) .mopt[for="crv-sq"],
body:has(#crv-ci:focus-visible) .mopt[for="crv-ci"],
body:has(#show-nav:focus-visible) .mopt[for="show-nav"],
body:has(#show-scroll:focus-visible) .mopt[for="show-scroll"],
body:has(#scroll-all:focus-visible) .mopt[for="scroll-all"],
body:has(#fn-1:focus-visible) .mopt[for="fn-1"],
body:has(#fn-3:focus-visible) .mopt[for="fn-3"],
body:has(#fn-4:focus-visible) .mopt[for="fn-4"],
body:has(#fn-5:focus-visible) .mopt[for="fn-5"],
body:has(#fn-8:focus-visible) .mopt[for="fn-8"],
body:has(#fs-1:focus-visible) .mopt[for="fs-1"],
body:has(#fs-2:focus-visible) .mopt[for="fs-2"],
/* FOCUS-LIST-END */
body:has(#mode-dark:focus-visible) .modebtn,
body:has(#win-min:focus-visible)   .tb-btn.is-min,
body:has(#win-closed:focus-visible) .tb-btn.is-close,
body:has(#bg-file:focus-visible)   .mopt[for="bg-file"] {
  outline: 2px solid var(--pop);
  outline-offset: -2px;
}


/* ==========================================================================
   09  DESKTOP-ONLY NOTICE
   ========================================================================== */

/* The panel's look is unconditional; only whether it shows is a condition,
   and there are two of those now. Keeping the styling out of both branches
   means the notice cannot end up looking different depending on which one
   put it on screen. */
.toosmall {
  display: none;
  max-width: 420px;
  margin: 20px;
  background: var(--face);
  border: 2px solid var(--ink);
  box-shadow: var(--drop-lg);
}
.toosmall p:last-child { padding: 16px 18px; font-size: 11px; line-height: 18px; }

/* WHEN THIS SHOWS, AND WHY IT ALMOST NEVER SHOULD.

   It used to show at 1180 x 700, which is above the viewport an ordinary
   laptop actually has once the browser's own chrome is subtracted — a
   1366 x 768 display leaves about 640px of page. So visitors were handed
   this notice in place of the site on hardware the site could have served
   perfectly well, and the same thing happened again on zoom-out, from a
   separate rule that compared the viewport against screen.width.

   Both are gone. The window scales to whatever room there is (see --fit),
   which covers zooming in, zooming out and small displays with one
   mechanism, and none of them reach this notice.

   What is left is the genuine floor. Below roughly half scale the 11px type
   is drawn at 5 or 6 pixels and stops being type; that is a real failure and
   worth saying so plainly, rather than showing an unreadable smudge. The
   script sets .is-tiny at that point. */
html.is-tiny .window,
html.is-tiny .intro,
html.is-tiny .deskicon { display: none !important; }
html.is-tiny .toosmall { display: block; }

/* The same floor as a media query, for the case where the script has not run
   and --fit is stuck at 1. The thresholds are the two viewports at which the
   scale would have fallen to 0.5: 1280 x 0.5 and 872 x 0.5, plus the margin.
   Without this a scriptless visit on a phone would get the full-size window
   overflowing off three sides. */
@media (max-width: 640px), (max-height: 436px) {
  .window, .intro, .deskicon { display: none !important; }
  .toosmall { display: block; }
}
