/* ============================================================
   V.S — Portfolio
   Retro CRT portfolio. Design tokens lifted from Figma:
   figma.com/design/uZhuQYz9HyFXvj0z3G4sNm/Portfolio
   ============================================================ */

/* ---------- Self-hosted fonts (from the Figma file) ---------- */
@font-face {
  font-family: 'PP NeueBit';
  src: url('../assets/fonts/PPNeueBit-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'PP Mondwest';
  src: url('../assets/fonts/PPMondwest-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  /* palette */
  /* Near black rather than pure black, with a little warmth low down
     where the fire is. Flat #000 beside a lit monitor reads as a hole
     in the page rather than as a dark room. */
  --room-bg:      #070605;
  --room-wash:    radial-gradient(120% 70% at 50% 108%,
                    rgba(224,122,40,0.16) 0%,
                    rgba(120,52,14,0.07) 38%,
                    transparent 72%);
  --grad-top:     #dfdfdf;
  --grad-mid:     #e4a00c;
  --grad-bot:     #db5400;
  --screen-grad:  linear-gradient(180deg,
                    var(--grad-top) 2.4%,
                    var(--grad-mid) 49.5%,
                    var(--grad-bot) 85%);

  /* The error screens use the gradient as it is drawn in the reference:
     a warm cream at the very top rather than a neutral grey, and stops
     that run the full height. The site gradient lands its last stop at
     85%, which leaves the bottom sixth a flat slab, and that is the
     banding that shows on a large area of unbroken colour. The extra
     mid stops keep the ramp even. */
  --err-grad:     linear-gradient(180deg,
                    #e4d6c6   0%,
                    #dcc39d  14%,
                    #d9b478  27%,
                    #d7a658  40%,
                    #d69a3c  53%,
                    #d28a32  66%,
                    #cf7a2c  79%,
                    #cb6627  91%,
                    #c85924 100%);

  --red:          #ef0000;   /* Hello. / Welcome */
  --red-brand:    #db1c00;   /* v.s wordmark */
  --blue:         #165ddd;   /* clock, code tags */
  --menu-ink:     #b5a483;   /* menu bar labels */
  --menu-bar:     #221a16;   /* menu bar fill */
  --label-ink:    #414141;   /* folder labels */
  --ink-dark:     #16110c;
  --ink-white:    #f7f1e6;   /* verbs, on the coral end of the gradient */

  /* type */
  --bit:   'PP NeueBit', 'Silkscreen', monospace;   /* display / pixel */
  --mond:  'PP Mondwest', 'Silkscreen', monospace;  /* UI / body */

  /* Where the glass sits inside the monitor photo, as % of the image.
     Measured off bezel.png itself (the CRT interior runs x 455–1570,
     y 195–1015 of 2000px), then inset 2% so the photo's curved glass
     edge always covers our rectangle's corners. */
  /* The monitor frame. frame.webp is the photographed front bezel,
     1315 x 994, 9-sliced at 160 / 150 / 114 / 150 px. One source pixel
     is drawn at --px, which tracks the smaller side of the window, so
     the frame is the same weight on a laptop, a phone or a big screen.
     The glass insets are measured off the photo's opening, plus a hair
     so a thin dark rim of tube shows round the lit screen. */
  --px:     calc(100vmin / 1365);
  --bz-t:   calc(160 * var(--px));
  --bz-r:   calc(150 * var(--px));
  --bz-b:   calc(114 * var(--px));
  --bz-l:   calc(150 * var(--px));
  --gl-t:   calc(114 * var(--px));
  --gl-r:   calc(114 * var(--px));
  --gl-b:   calc(58  * var(--px));
  --gl-l:   calc(112 * var(--px));
  --gl-rad: calc(55  * var(--px));
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
  background: var(--room-bg);
  background-image: var(--room-wash);
  overflow: hidden;
  font-family: var(--mond);
  -webkit-font-smoothing: antialiased;
}

body { position: relative; }

/* ============================================================
   1. THE ROOM — the Blender render the site opens on.
   Everything is placed against a 16:9 frame that covers the
   viewport the way object-fit: cover would, so the copy and the
   glass stay locked to the render at any window size. Sizes are
   in cqw of that frame, measured off the Figma mock-up.
   ============================================================ */
.room {
  /* frame width, and its left edge. On windows narrower than 16:9 the
     crop leans left so the monitor (right of centre) stays in view. */
  --fw: max(100vw, 177.778vh);
  --fl: clamp(calc(100vw - var(--fw)), calc(50vw - var(--fw) * 0.62), 0px);
  --room-ink: #e2b46c;
  position: fixed;
  inset: 0;
  z-index: 200;
  overflow: hidden;
  background: var(--room-bg);
  cursor: pointer;
  transition: opacity 600ms ease;
}
.room.out  { opacity: 0; pointer-events: none; }
.room.gone { display: none; }

.room-frame {
  position: absolute;
  left: var(--fl);
  top: 50%;
  width: var(--fw);
  aspect-ratio: 16 / 9;
  transform: translateY(-50%);
  container-type: inline-size;
}
.room-still,
.room-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
/* the still sits over the video until the first frame is actually
   painting, so starting playback can never flash black */
.room-still { transition: opacity 120ms linear; }
.room.playing .room-still { opacity: 0; }

/* the visual on the monitor's glass — main.js sets its transform */
.room-glass {
  position: absolute;
  left: 0;
  top: 0;
  width: 400px;
  height: 300px;
  transform-origin: 0 0;
  overflow: hidden;
  transition: opacity 300ms ease;
}
/* what the glass shows: the site's own screen — gradient, v.s, the eye */
.room-glass {
  background: var(--screen-grad);
  border-radius: 4.5% / 6%;
}
.room-glass::after {             /* the same glare as .screen */
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 70% 40% at 30% 12%,
              rgba(255,255,255,0.16), transparent 62%);
  pointer-events: none;
}
.glass-mark {
  position: absolute;
  left: 10.2%;
  top: 12.1%;
  font: 700 12px/1 var(--bit);
  color: var(--red-brand);
}
.glass-eye {
  position: absolute;
  left: 50%;
  top: 48%;
  width: 34%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  /* inline SVG rather than a CSS mask: masks loaded from a file are
     blocked when index.html is opened straight from disk */
  color: var(--red-brand);
}

.room-glass[data-placeholder] {
  outline: 2px dashed rgba(60, 20, 0, 0.45);
  outline-offset: -10px;
}
.room-glass[data-placeholder]::after {
  content: 'your visual';
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font: 700 28px/1 'Silkscreen', var(--bit);
  color: rgba(60, 20, 0, 0.5);
}

.room-copy,
.room-enter {
  color: var(--room-ink);
  text-shadow: 0 0.15cqw 1.2cqw rgba(0, 0, 0, 0.45);
  transition: opacity 350ms ease, transform 350ms ease;
}
.room-copy {
  position: absolute;
  /* never closer than 5vw to the window edge when the frame is cropped */
  left: max(6.75cqw, calc(5vw - var(--fl)));
  top: 15.4%;
  width: 40cqw;
  font-family: var(--bit);
}
.room-hello {
  margin: 0 0 4.2cqw;
  font-size: 8.8cqw;
  line-height: 0.68;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.room-copy p {
  margin: 0 0 2.4cqw;
  max-width: 29.5cqw;
  font-size: 2.85cqw;
  line-height: 0.86;
}
.room-enter {
  position: absolute;
  /* centred on the window, not the (possibly cropped) frame */
  left: calc(50vw - var(--fl));
  bottom: 5.4%;
  transform: translateX(-50%);
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
  font: 700 2.6cqw/1 'Silkscreen', var(--bit);
  letter-spacing: 0.24em;
  word-spacing: 0.6em;
  white-space: nowrap;
  animation: room-blink 1.1s steps(1, end) infinite;
}
.room-enter .caret { letter-spacing: 0.1em; }
.room-enter:focus-visible { outline: 0.15cqw solid var(--room-ink); outline-offset: 0.8cqw; }
@keyframes room-blink { 50% { opacity: 0.25; } }

/* Enter pressed: the words step aside for the camera */
.room.entering .room-copy  { opacity: 0; transform: translateX(-1.5cqw); }
.room.entering .room-enter { opacity: 0; animation: none; }
.room.entering .room-glass { opacity: 0; }

/* ============================================================
   STAGE — holds the monitor photo. Scales/zooms as a unit.
   ============================================================ */
/* One camera position now: the monitor fills the window edge to edge,
   frame at the borders, no room either side and no control panel below.
   main.js briefly sets an explicit box on the stage to line the glass up
   with the last frame of the Blender move, then clears it, and these
   transitions carry it out to the full window. */
.stage {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: #0b0907;          /* the tube, seen as a rim round the glass */
  transition:
    left   1100ms cubic-bezier(0.65, 0, 0.35, 1),
    top    1100ms cubic-bezier(0.65, 0, 0.35, 1),
    width  1100ms cubic-bezier(0.65, 0, 0.35, 1),
    height 1100ms cubic-bezier(0.65, 0, 0.35, 1);
}

.bezel {
  position: absolute;
  inset: 0;
  box-sizing: border-box;
  border-style: solid;
  border-width: var(--bz-t) var(--bz-r) var(--bz-b) var(--bz-l);
  border-image: url('../assets/img/frame.webp') 160 150 114 150 /
                var(--bz-t) var(--bz-r) var(--bz-b) var(--bz-l) stretch;
  pointer-events: none;
  user-select: none;
  z-index: 2;
}

/* ============================================================
   SCREEN — the glowing glass. Everything lives inside it.
   ============================================================ */
.screen {
  position: absolute;
  top: var(--gl-t);
  right: var(--gl-r);
  bottom: var(--gl-b);
  left: var(--gl-l);
  background: var(--screen-grad);
  border-radius: var(--gl-rad);
  overflow: hidden;
  z-index: 1;
  isolation: isolate;
  cursor: pointer;
}

/* glare */
.screen::after {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(ellipse 70% 40% at 30% 12%,
              rgba(255,255,255,0.16), transparent 62%);
  pointer-events: none;
  z-index: 60;
}
/* Grain, not scanlines. The line pattern was fighting the pixel type
   at small sizes; a fine noise reads as a lit phosphor surface and
   leaves the artwork alone. The SVG is a turbulence filter, so there
   is no image to load. */
.screen::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
  background-size: 160px 160px;
  mix-blend-mode: overlay;
  opacity: 0.22;
  pointer-events: none;
  z-index: 61;
}

/* Screen content is authored against a 463x350 box and scaled with
   container queries so text tracks the screen size exactly. */
.screen-inner {
  position: absolute;
  inset: 0;
  container-type: size;
  container-name: screen;
}

/* ============================================================
   VIEWS
   ============================================================ */
.view {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 420ms ease, visibility 420ms;
  z-index: 10;
}
.view.active {
  opacity: 1;
  visibility: visible;
}

/* ---------------- LOADING ---------------- */
#view-loading { display: grid; place-items: center; }
/* Proportions taken off the Figma frame: globe ~18.6% of the screen
   width, the word ~5%, the pair sitting a little above centre. */
#view-loading .stack {
  display: grid;
  justify-items: center;
  gap: 4.4cqh;
  transform: translateY(-3cqh);
}

.globe {
  position: relative;
  width: 18.6cqw;
  height: 18.6cqw;
}
.globe-clip {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: 50%;
}
.globe-track {
  position: absolute;
  inset: 0;
  width: 200%;
  display: flex;
  animation: globe-turn 3.6s steps(16) infinite;
}
.globe-land {
  flex: 0 0 50%;
  height: 100%;
  image-rendering: pixelated;
}
.globe-rim {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  image-rendering: pixelated;
}
@keyframes globe-turn { to { transform: translateX(-50%); } }

.loading-label {
  font-family: var(--mond);
  font-size: 5cqw;
  color: var(--red);
  letter-spacing: 0.01em;
  line-height: 1;
}

/* ---------------- WELCOME ---------------- */
/* Centred as a block, matching the Figma landing frame where "Welcome"
   and the three verbs share one optical centre. */
#view-welcome {
  display: grid;
  place-content: center;
  justify-items: center;
  text-align: center;
}
.welcome-word {
  font-family: var(--bit);
  font-size: 16.9cqw;
  line-height: 0.78;
  color: var(--red);
  margin: 0 0 6cqh;
}
.verbs {
  display: flex;
  justify-content: center;
  gap: 11.75cqw;
  font-family: var(--mond);
  font-size: 2.4cqw;
  color: #fff;
}
.verbs span { opacity: 0; transform: translateY(6px); }
#view-welcome.active .verbs span {
  animation: rise 520ms cubic-bezier(0.2,0.9,0.3,1) forwards;
}
#view-welcome.active .verbs span:nth-child(1) { animation-delay: 260ms; }
#view-welcome.active .verbs span:nth-child(2) { animation-delay: 400ms; }
#view-welcome.active .verbs span:nth-child(3) { animation-delay: 540ms; }
@keyframes rise { to { opacity: 1; transform: none; } }

/* wordmark, top-left on welcome */
.wordmark {
  position: absolute;
  left: 10.2cqw;
  top: 12.1cqh;
  font-family: var(--bit);
  font-size: 2.4cqw;
  color: var(--red-brand);
  z-index: 40;
  line-height: 1;
}

/* ---------------- HOME ---------------- */
/* Sizes below are Figma pixel values ÷ 1512 (the frame width), expressed
   in cqw so the whole screen scales as one unit. */

/* menu bar — flush to the top edge of the glass */
.menubar {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 7.5cqh;
  background: var(--menu-bar);
  display: flex;
  align-items: center;
  gap: 4.8cqw;
  padding: 0 3.4cqw;
  z-index: 40;
}
/* The icon's viewBox is a 32x32 square with the eye artwork (30.48 x
   18.29) padded inside it, so a square box renders it undistorted.
   object-fit is a guard in case the art is ever swapped for a
   non-square export. */
.menubar .eye {
  width: 2.6cqw;
  height: 2.6cqw;
  flex: none;
  object-fit: contain;
  image-rendering: pixelated;
}
.menubar button {
  all: unset;
  cursor: pointer;
  font-family: var(--mond);
  font-size: 1.6cqw;
  color: var(--menu-ink);
  line-height: 1;
  transition: color 140ms ease;
}
.menubar button:hover,
.menubar button:focus-visible { color: #f0e6d2; }
/* Sound toggle. It sits with the clock rather than the menus,
   because it reports a state rather than opening something. */
.menubar .snd {
  all: unset;
  margin-left: auto;
  cursor: pointer;
  display: flex;
  align-items: center;
  padding: 0.4cqw;
}
.menubar .snd svg {
  width: 2.1cqw;
  height: 2.1cqw;
  display: block;
  fill: var(--menu-ink);
  transition: fill 140ms ease;
}
.menubar .snd:hover svg,
.menubar .snd:focus-visible svg { fill: #f0e6d2; }
.menubar .snd .snd-wave { display: none; }
.menubar .snd[aria-pressed="true"] svg { fill: var(--blue); }
.menubar .snd[aria-pressed="true"] .snd-wave { display: block; }
.menubar .snd[aria-pressed="true"] .snd-off { display: none; }

.menubar .clock {
  margin-left: 1.4cqw;
  font-family: var(--bit);
  font-size: 2.4cqw;
  color: var(--blue);
  line-height: 1;
}

/* Verb strip — the same three words the Figma boot frame carries, and
   the Welcome screen echoes. Closes the lower band, which otherwise sat
   empty over the most saturated part of the gradient. */
.home-verbs {
  position: absolute;
  left: 8.5cqw;
  right: 8.5cqw;
  bottom: 6.5cqh;
  display: flex;
  justify-content: space-between;
  font-family: var(--mond);
  font-size: 2.4cqw;
  color: var(--ink-white);
  z-index: 20;
}
.home-verbs span { transition: opacity 160ms ease; }
.home-verbs:hover span { opacity: 0.55; }
.home-verbs span:hover { opacity: 1; }

/* status bar — mirrors the menu bar so the field is framed top and
   bottom. Without it the lower third of the screen reads as dead space. */
.statusbar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 6cqh;
  visibility: hidden;
  background: var(--menu-bar);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 3.4cqw;
  font-family: var(--bit);
  font-size: 1.7cqw;
  color: var(--menu-ink);
  z-index: 40;
}
.statusbar a { color: var(--menu-ink); text-decoration: none; }
.statusbar a:hover { color: #f0e6d2; }

.availability {
  position: absolute;
  top: 10.5cqh;
  right: 3.4cqw;
  text-align: right;
  z-index: 20;
  font-family: var(--bit);
  font-size: 1.7cqw;
  line-height: 1.5;
  color: var(--ink-dark);
}
.availability .status {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.9cqw;
}
.availability .status::after {
  content: '';
  width: 1.1cqw;
  height: 1.1cqw;
  background: var(--blue);
  flex: none;
}
.availability .where { color: #6d4a2a; }

/* desktop folders */
.desktop { position: absolute; inset: 0; z-index: 20; }

.folder {
  all: unset;
  position: absolute;
  left: var(--x);
  top: var(--y);
  transform: translate(-50%, -50%);
  display: grid;
  justify-items: center;
  gap: 0.7cqw;
  cursor: pointer;
  width: 7.5cqw;
  transition: transform 150ms cubic-bezier(0.2,0.9,0.3,1);
}
.folder:hover  { transform: translate(-50%, calc(-50% - 4px)); }
.folder:active { transform: translate(-50%, -50%) scale(0.95); }
.folder:focus-visible .ficon { outline: 2px solid var(--red); outline-offset: 3px; }

.folder .ficon {
  width: 100%;
  height: auto;
  image-rendering: pixelated;
  filter: drop-shadow(0 1px 0 rgba(0,0,0,0.22));
  transition: filter 150ms ease;
}
.folder:hover .ficon {
  filter: drop-shadow(0 3px 0 rgba(0,0,0,0.26)) brightness(1.08);
}
.folder .flabel {
  font-family: var(--bit);
  font-size: 1.9cqw;
  color: var(--label-ink);
  line-height: 1;
  text-align: center;
  white-space: nowrap;
  /* The wallpaper runs from near white at the top to deep orange at the
     bottom, so a single ink colour cannot hold on both. A soft light
     halo lifts the label off the dark end without showing on the pale
     end, where there is nothing for it to contrast against. */
  text-shadow: 0 1px 0 rgba(255,245,230,0.45), 0 0 6px rgba(255,238,220,0.35);
}
.folder:hover .flabel { color: var(--ink-dark); }

/* ============================================================
   PROJECT WINDOW
   ============================================================ */

.win-layer {
  position: absolute;
  inset: 0;
  z-index: 80;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 6cqh 6cqw;
  background: rgba(24,12,6,0.34);
}
.win-layer.open { display: flex; }

.window {
  width: 100%;
  max-width: 74cqw;
  max-height: 100%;
  background: #ece5d3;
  border: 0.55cqh solid var(--ink-dark);
  box-shadow: 0.9cqh 1.1cqh 0 rgba(28,26,23,0.34);
  display: flex;
  flex-direction: column;
  animation: winopen 300ms cubic-bezier(0.2, 1.5, 0.4, 1);
}
@keyframes winopen {
  0%   { transform: scale(0.2) translateY(14%); opacity: 0; filter: blur(2px); }
  60%  { opacity: 1; filter: blur(0); }
  100% { transform: none; opacity: 1; }
}

.win-title {
  display: flex;
  align-items: center;
  gap: 1.6cqw;
  height: 8cqh;
  padding: 0 1.6cqw;
  border-bottom: 0.55cqh solid var(--ink-dark);
  flex: none;
}
.win-title .close {
  all: unset;
  width: 3.4cqh; height: 3.4cqh;
  border: 0.45cqh solid var(--ink-dark);
  cursor: pointer;
  flex: none;
}
.win-title .close:hover { background: var(--red); }
.win-title .name {
  font-family: var(--bit);
  font-size: 4.4cqh;
  color: var(--ink-dark);
  line-height: 1;
}
.win-title .rule {
  flex: 1;
  height: 60%;
  background: repeating-linear-gradient(0deg,
    var(--ink-dark) 0 1.5px, transparent 1.5px 5px);
}

.win-body {
  padding: 4cqh 3cqw;
  overflow-y: auto;
  color: #2a2620;
}
.win-body .kicker {
  font-family: var(--bit);
  font-size: 3.2cqh;
  color: var(--blue);
  letter-spacing: 0.08em;
  margin: 0 0 1.6cqh;
}
.win-body h2 {
  font-family: var(--bit);
  font-size: 8cqh;
  color: var(--red);
  margin: 0 0 2.4cqh;
  line-height: 1;
}
.win-body p {
  font-family: var(--mond);
  font-size: 4cqh;
  line-height: 1.42;
  margin: 0 0 2.2cqh;
}
.win-body .cta {
  display: inline-block;
  margin-top: 1.4cqh;
  font-family: var(--bit);
  font-size: 4cqh;
  color: #ece5d3;
  background: var(--ink-dark);
  padding: 1.4cqh 2.4cqw;
  text-decoration: none;
  transition: background 140ms ease;
}
.win-body .cta:hover { background: var(--red); }
.win-body a.link { color: var(--blue); }

/* ============================================================
   Reduced motion
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .stage, .view, .window { transition-duration: 1ms; animation: none; }
  .globe-track, .verbs span, .room-enter { animation: none; }
  .verbs span { opacity: 1; transform: none; }
}

/* ============================================================
   Small screens — the whole machine no longer earns its space,
   so we let the glass dominate. JS also skips straight to the
   zoomed camera on narrow viewports.
   ============================================================ */
@media (max-width: 820px) {
  .stage { width: min(86vh, 96vw); }
  .folder { width: 17cqw; }
  .menubar { gap: 3.2cqw; }
  .window { max-width: 88cqw; }
}

/* the eye is a control now: it opens the CV */
.menubar .eye { cursor: pointer; transition: transform 140ms ease, filter 140ms ease; }
.menubar .eye:hover { transform: scale(1.12); filter: brightness(1.25); }
.menubar .eye:focus-visible { outline: 0.2cqw solid var(--menu-ink); outline-offset: 0.3cqw; }

/* a square icon (the About Me floppy) should not inherit the folder's
   landscape proportions */
.folder .ficon--sq { width: 72%; margin: 0 auto; }



/* No footer. The bar under the desktop only appears while something is
   minimised and needs somewhere to wait. */
.statusbar:has(.wm-task) { visibility: visible; }


/* ============================================================
   PORTRAIT — phones, or any window taller than it is wide
   Everything on the glass is sized as a share of its width, which is
   right for a laptop and four times too small on a phone. This block
   re-proportions the same elements for a tall, narrow glass rather
   than shrinking the laptop layout. Keyed to the glass's own shape
   with a container query, so it never touches a wide screen.
   ============================================================ */
@container screen (max-aspect-ratio: 1/1) {

  /* window chrome scales through --q (see wm.css) */
  .wm-layer, .statusbar { --q: 3cqw; }

  /* ---- menu bar ---- */
  .menubar {
    height: 13cqw;
    gap: 4.2cqw;
    padding: 0 4.5cqw;
  }
  .menubar .eye { width: 6.6cqw; height: 6.6cqw; }
  .menubar button { font-size: 4.5cqw; }
  /* two menu items give way to room: About is also the floppy on the
     desktop, and View and Edit (welcome, colophon) are the least needed */
  .menubar button[data-menu="colophon"],
  .menubar button[data-menu="welcome"] { display: none; }
  .menubar .snd { padding: 1.2cqw; }
  .menubar .snd svg { width: 5.4cqw; height: 5.4cqw; }
  .menubar .game { margin-left: 0; padding: 1.2cqw; }
  .menubar .game svg { height: 4.4cqw; }
  .menubar .clock { font-size: 4.8cqw; margin-left: 1.5cqw; }
  .clock-day { display: none; }

  /* ---- availability, under the bar ---- */
  .availability {
    top: 17cqw;
    right: 4.5cqw;
    font-size: 4cqw;
    line-height: 1.45;
  }

  /* ---- the files ---- */
  .folder {
    left: var(--px);
    top: var(--py);
    width: 22cqw;
    gap: 2cqw;
  }
  .folder .flabel { font-size: 4.6cqw; }
  .folder .ficon--sq { width: 74%; }

  /* ---- verbs along the bottom ---- */
  .home-verbs {
    left: 7cqw;
    right: 7cqw;
    bottom: 5cqh;
    font-size: 5.4cqw;
  }

  /* ---- welcome ---- */
  .wordmark { left: 7cqw; top: 6cqw; font-size: 5.4cqw; }
  .welcome-word { font-size: 23cqw; margin-bottom: 5cqh; }
  .verbs { font-size: 5cqw; gap: 6cqw; }

  /* ---- loading ---- */
  .globe { width: 40cqw; height: 40cqw; }
  .loading-label { font-size: 9cqw; }

  /* ---- windows: on a phone a window is the whole glass under the bar ---- */
  .wm-win {
    left: 0 !important;
    top: 13cqw !important;
    width: 100% !important;
    height: calc(100% - 13cqw) !important;
    border-radius: 0;
    animation: none;
  }
  .wm-rs { display: none; }
  .wm-btn--max { display: none; }
  .statusbar { height: 12cqw; padding: 0 4cqw; font-size: 4cqw; }
}


/* ============================================================
   THE ROOM ON A PHONE
   The intro's words are sized against the 16:9 render, which on a
   phone is about four screens wide. Here they are sized against the
   screen instead, stacked above the monitor, and the crop is centred
   on the monitor (about 77% across the render) rather than leaning.
   ============================================================ */
.enter-tap { display: none; }
@media (hover: none) {
  .enter-key { display: none; }
  .enter-tap { display: inline; }
}
@media (max-aspect-ratio: 1/1) {
  .room { --fl: clamp(calc(100vw - var(--fw)), calc(50vw - var(--fw) * 0.77), 0px); }
  .room-copy {
    left: calc(7vw - var(--fl));
    top: 9vh;
    width: 86vw;
  }
  .room-hello {
    font-size: 14vw;
    line-height: 0.8;
    margin-bottom: 6vw;
  }
  .room-copy p {
    max-width: 80vw;
    font-size: 4.7vw;
    line-height: 1.15;
    margin-bottom: 3.4vw;
  }
  .room-enter {
    bottom: 7vh;
    font-size: 4.4vw;
    letter-spacing: 0.2em;
    word-spacing: 0.4em;
  }
}


/* ============================================================
   CURSOR
   A pixel arrow, red with a white outline so it holds on the pale
   glass and the dark room alike, and a pixel hand over anything that
   does something when clicked. Drawn at 1x and 2x so it stays sharp on
   Retina screens. Mouse and trackpad only: a phone has no cursor.
   Each rule is written three times so every browser gets the
   sharpest version it understands.
   ============================================================ */
@media (pointer: fine) {
  html, body, .screen {
    cursor: url("../assets/cursor/arrow.png") 1 1, auto;
    cursor: -webkit-image-set(url("../assets/cursor/arrow.png") 1x, url("../assets/cursor/arrow@2x.png") 2x) 1 1, auto;
    cursor: image-set(url("../assets/cursor/arrow.png") 1x, url("../assets/cursor/arrow@2x.png") 2x) 1 1, auto;
  }
  a[href], button, [role="button"], summary, label, select,
  [data-zoom],
  .room, .folder, .menubar button, .wm-btn, .wm-task, .bb-over {
    cursor: url("../assets/cursor/hand.png") 10 1, pointer;
    cursor: -webkit-image-set(url("../assets/cursor/hand.png") 1x, url("../assets/cursor/hand@2x.png") 2x) 10 1, pointer;
    cursor: image-set(url("../assets/cursor/hand.png") 1x, url("../assets/cursor/hand@2x.png") 2x) 10 1, pointer;
  }
}
