/* ============================================================
   Desktop — a personal homepage shaped like macOS
   ============================================================ */

:root{
  /* wallpaper framing — which part of the photo survives the crop.
     The source is a native 16:9 frame, so most monitors show it uncropped;
     the slight upward bias only matters on taller ratios, where it trims
     foreground grass before it touches the headline. */
  --wall-focus: 50% 45%;

  /* the chrome pointer, with its hotspot on the arrow tip */
  --cursor: url("assets/cursor.png") 1 0, default;

  --menubar-h: 26px;
  --dock-pad: 6px;
  --dock-icon: 54px;          /* resting icon size */
  --dock-max: 1.85;           /* magnification multiplier under the cursor */

  --hairline: rgba(255,255,255,.16);
  --chrome-text: rgba(255,255,255,.94);

  --ease-out: cubic-bezier(.22,.61,.36,1);

  /* sampled from the photograph — stands in until the image paints */
  --sky: #2c3d27;

  --sticky-1: #FFF07A;
  --sticky-2: #FDE24A;
}

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

html,body{ height:100%; }

body{
  margin:0;
  overflow:hidden;
  background:var(--sky);
  font:13px/1.45 -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI",
       "Helvetica Neue", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  color:var(--chrome-text);
  -webkit-tap-highlight-color:transparent;
}

/* ─────────────────────────── the pointer ───────────────────────────
   The chrome arrow stands in for the system cursor everywhere, except
   over text you can actually type into, where an I-beam still earns
   its keep. `image-set` hands Retina screens the @2x bitmap.          */

body, body *{ cursor:var(--cursor); }

/* the test needs a *complete* cursor value — hotspot and fallback keyword
   included — or it never matches and Retina keeps the 1x bitmap */
@supports (cursor: image-set(url("assets/cursor.png") 1x, url("assets/cursor@2x.png") 2x) 1 0, default){
  :root{
    --cursor:image-set(url("assets/cursor.png") 1x, url("assets/cursor@2x.png") 2x) 1 0, default;
  }
}

.sticky__body,
.win__page{ cursor:text; }

.sticky__grip{ cursor:nwse-resize; }

/* ────────────────────────── wallpaper ────────────────────────── */

.wallpaper{
  position:fixed;
  inset:0;
  z-index:0;
  background:url("assets/wallpaper.jpg") var(--wall-focus) / cover no-repeat var(--sky);
  filter:saturate(1.04);
}

/* A portrait screen crops this landscape shot to a narrow vertical slice
   through the middle, plain sky above and foreground grass below. Overscaling
   past `cover` buys back a little slack to trim both and centre the crop on
   the hills instead. */
@media (max-aspect-ratio: 1/1){
  .wallpaper{ background-size:auto 122%; background-position:50% 38%; }
}

/* light vignette so the chrome always has something to sit on */
.wallpaper::after{
  content:"";
  position:absolute;
  inset:0;
  background:
    linear-gradient(to bottom, rgba(0,20,40,.28) 0%, rgba(0,20,40,0) 14%),
    radial-gradient(120% 90% at 50% 55%, rgba(0,0,0,0) 55%, rgba(0,15,30,.22) 100%);
}

/* ────────────────────────── menu bar ────────────────────────── */

.menubar{
  position:fixed;
  top:0; left:0; right:0;
  z-index:400;
  height:var(--menubar-h);
  display:flex;
  align-items:stretch;
  justify-content:space-between;
  padding:0 8px;
  /* heavy enough that white text survives a near-white wallpaper —
     this photo runs almost to paper-white along the horizon */
  background:linear-gradient(to bottom, rgba(24,30,40,.52), rgba(24,30,40,.42));
  backdrop-filter:blur(28px) saturate(180%);
  -webkit-backdrop-filter:blur(28px) saturate(180%);
  box-shadow:0 .5px 0 rgba(255,255,255,.10) inset, 0 1px 6px rgba(0,0,0,.10);
  font-size:13px;
  user-select:none;
}

.menubar__left,
.menubar__right{ display:flex; align-items:stretch; gap:1px; }
.menubar__right{ gap:2px; }

.menu,
.status{
  appearance:none;
  border:0;
  background:transparent;
  color:var(--chrome-text);
  font:inherit;
  letter-spacing:.005em;
  padding:0 9px;
  display:flex;
  align-items:center;
  border-radius:5px;
  white-space:nowrap;
}

.menu--app{ font-weight:600; }

.menu:hover,
.status:hover{ background:rgba(255,255,255,.16); }

.menu.is-open{ background:rgba(255,255,255,.26); }

.applemark{ width:13px; height:16px; fill:currentColor; display:block; }

.status svg{ display:block; }
.ico-battery{ width:26px; height:12px; }
.ico-wifi   { width:16px; height:12px; }
.ico-search { width:14px; height:14px; }
.ico-cc     { width:16px; height:13px; }

.status--clock{
  font-variant-numeric:tabular-nums;
  padding-right:6px;
  letter-spacing:.01em;
}

/* ─────────────────────── dropdown menus ─────────────────────── */

.menu-layer{
  position:fixed;
  inset:0;
  z-index:390;
}

.dropdown{
  position:absolute;
  min-width:200px;
  padding:5px;
  border-radius:9px;
  background:rgba(246,246,248,.72);
  backdrop-filter:blur(34px) saturate(180%);
  -webkit-backdrop-filter:blur(34px) saturate(180%);
  border:.5px solid rgba(0,0,0,.14);
  box-shadow:0 12px 34px rgba(0,0,0,.26), 0 0 0 .5px rgba(255,255,255,.5) inset;
  color:#1c1c1e;
  font-size:13.5px;
  transform-origin:top left;
  animation:pop .11s var(--ease-out);
}

@keyframes pop{ from{ opacity:0; transform:translateY(-3px) scale(.985); } }

.dropdown__item{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:26px;
  padding:4px 9px;
  border-radius:5px;
  white-space:nowrap;
}
.dropdown__item:hover{ background:#0a6fdc; color:#fff; }
.dropdown__item[aria-disabled="true"]{ color:rgba(0,0,0,.32); pointer-events:none; }
.dropdown__item kbd{
  font:inherit;
  color:rgba(0,0,0,.42);
  letter-spacing:.04em;
}
.dropdown__item:hover kbd{ color:rgba(255,255,255,.78); }

.dropdown__sep{
  height:.5px;
  margin:5px 9px;
  background:rgba(0,0,0,.16);
}

/* ────────────────────────── desktop ────────────────────────── */

.desktop{
  position:fixed;
  inset:var(--menubar-h) 0 0 0;
  z-index:10;
}

/* desktop icons — top-right, filling downward then leftward, like Finder */
.icons{
  position:absolute;
  top:10px;
  right:12px;
  bottom:110px;
  margin:0;
  padding:0;
  list-style:none;
  display:flex;
  flex-flow:column wrap;
  align-content:flex-end;
  gap:2px;
}

.icon{
  width:96px;
  padding:6px 4px 7px;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:5px;
  border-radius:7px;
  outline:none;
}

.icon__art{
  width:66px;
  height:54px;
  display:grid;
  place-items:center;
  filter:drop-shadow(0 3px 6px rgba(0,0,0,.30));
}
.icon__art img{
  max-width:100%;
  max-height:100%;
  display:block;
  object-fit:contain;
  -webkit-user-drag:none;
  user-select:none;
}

.icon__label{
  max-width:100%;
  padding:1.5px 6px 2.5px;
  border-radius:5px;
  font-size:12px;
  line-height:1.25;
  text-align:center;
  color:#fff;
  /* a shadow alone disappears over the pale end of this wallpaper, so the
     label carries its own scrim */
  background:rgba(20,26,34,.34);
  backdrop-filter:blur(3px);
  -webkit-backdrop-filter:blur(3px);
  text-shadow:0 1px 2px rgba(0,0,0,.5);
  overflow-wrap:anywhere;
}

.icon.is-selected .icon__art{ filter:drop-shadow(0 2px 5px rgba(0,0,0,.34)) brightness(.86); }
.icon.is-selected .icon__label{
  background:#0a6fdc;
  text-shadow:none;
}
.icon:focus-visible{ box-shadow:0 0 0 3px rgba(255,255,255,.55); }

/* ───────────────────────── sticky note ───────────────────────── */

.sticky{
  position:absolute;
  left:50%;
  top:46%;
  translate:-50% -50%;
  width:340px;
  height:300px;
  min-width:190px;
  min-height:140px;
  display:flex;
  flex-direction:column;
  border-radius:5px;
  overflow:hidden;
  background:linear-gradient(180deg, var(--sticky-1), var(--sticky-2));
  box-shadow:
    0 1px 1px rgba(0,0,0,.14),
    0 14px 30px rgba(0,0,0,.24),
    0 34px 70px rgba(0,0,0,.20),
    0 0 0 .5px rgba(0,0,0,.10);
  color:#2a2200;
}

.sticky.is-dragging{
  box-shadow:
    0 1px 1px rgba(0,0,0,.14),
    0 26px 54px rgba(0,0,0,.32),
    0 60px 110px rgba(0,0,0,.24),
    0 0 0 .5px rgba(0,0,0,.10);
}

.sticky__bar{
  flex:0 0 22px;
  display:flex;
  align-items:center;
  gap:7px;
  padding:0 8px;
  background:linear-gradient(180deg, rgba(255,255,255,.46), rgba(255,255,255,.10));
  border-bottom:.5px solid rgba(0,0,0,.13);
  user-select:none;
}

.sticky__dots{ display:flex; gap:5px; }
.sticky__dots i{
  width:9px; height:9px;
  border-radius:50%;
  background:rgba(0,0,0,.16);
  box-shadow:0 0 0 .5px rgba(0,0,0,.10) inset;
}
.sticky:hover .sticky__dots i:nth-child(1){ background:#FF5F57; }
.sticky:hover .sticky__dots i:nth-child(2){ background:#FEBC2E; }
.sticky:hover .sticky__dots i:nth-child(3){ background:#28C840; }

.sticky__title{
  font-size:11.5px;
  font-weight:600;
  color:rgba(0,0,0,.45);
  letter-spacing:.01em;
}

.sticky__body{
  flex:1 1 auto;
  width:100%;
  border:0;
  outline:none;
  resize:none;
  background:transparent;
  padding:11px 14px 16px;
  /* -apple-system resolves to SF Pro on macOS; the rest are fallbacks that
     share its proportions for anyone reading this off a Mac */
  font:14.5px/1.58 -apple-system, BlinkMacSystemFont, "SF Pro Text",
       "Inter", "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif;
  letter-spacing:-.003em;
  color:#332a00;
}
.sticky__body::placeholder{ color:rgba(0,0,0,.30); }
.sticky__body::-webkit-scrollbar{ width:9px; }
.sticky__body::-webkit-scrollbar-thumb{
  background:rgba(0,0,0,.20);
  border-radius:9px;
  border:2.5px solid transparent;
  background-clip:content-box;
}

/* bottom-right resize grip */
.sticky__grip{
  position:absolute;
  right:0; bottom:0;
  width:16px; height:16px;
  cursor:nwse-resize;
}
.sticky__grip::before{
  content:"";
  position:absolute;
  right:3px; bottom:3px;
  width:8px; height:8px;
  border-right:1.5px solid rgba(0,0,0,.26);
  border-bottom:1.5px solid rgba(0,0,0,.26);
  border-radius:0 0 2px 0;
}

/* ──────────────────────────── dock ──────────────────────────── */

.dock-zone{
  position:fixed;
  left:0; right:0; bottom:0;
  z-index:300;
  display:flex;
  justify-content:center;
  padding-bottom:5px;
  pointer-events:none;
}

.dock{
  pointer-events:auto;
  max-width:calc(100vw - 16px);
  padding:var(--dock-pad);
  border-radius:20px;
  background:rgba(255,255,255,.16);
  backdrop-filter:blur(38px) saturate(190%);
  -webkit-backdrop-filter:blur(38px) saturate(190%);
  box-shadow:
    0 0 0 .5px rgba(255,255,255,.30) inset,
    0 0 0 .5px rgba(0,0,0,.16),
    0 12px 34px rgba(0,0,0,.26);
}

.dock__list{
  margin:0;
  padding:0;
  list-style:none;
  display:flex;
  align-items:flex-end;
  gap:3px;
  height:var(--dock-icon);
}

.dock__item{
  --m:1;                                   /* set by app.js on hover */
  position:relative;
  width:calc(var(--dock-icon) * var(--m));
  display:flex;
  align-items:flex-end;
  justify-content:center;
  transition:width .16s var(--ease-out);
}

.dock__btn{
  appearance:none;
  border:0;
  padding:0;
  background:transparent;
  width:calc(var(--dock-icon) * var(--m));
  height:calc(var(--dock-icon) * var(--m));
  transition:width .16s var(--ease-out), height .16s var(--ease-out);
  transform-origin:bottom center;
}

.dock__btn .app{
  width:100%;
  height:100%;
  display:block;
  filter:drop-shadow(0 3px 6px rgba(0,0,0,.26));
}

.dock__btn:active{ translate:0 -2px; }

/* running-app indicator */
.dock__item[data-running="true"]::after{
  content:"";
  position:absolute;
  bottom:-4.5px;
  width:4px; height:4px;
  border-radius:50%;
  background:rgba(255,255,255,.92);
  box-shadow:0 0 3px rgba(0,0,0,.4);
}

.dock__sep{
  width:1px;
  height:calc(var(--dock-icon) * .78);
  margin:0 6px;
  align-self:center;
  background:rgba(255,255,255,.34);
}

/* tooltip */
.dock__item::before{
  content:attr(data-label);
  position:absolute;
  bottom:calc(100% + 12px);
  left:50%;
  translate:-50% 0;
  padding:3px 9px 4px;
  border-radius:6px;
  font-size:12.5px;
  color:#1c1c1e;
  white-space:nowrap;
  background:rgba(246,246,248,.82);
  backdrop-filter:blur(20px) saturate(180%);
  -webkit-backdrop-filter:blur(20px) saturate(180%);
  border:.5px solid rgba(0,0,0,.14);
  box-shadow:0 6px 18px rgba(0,0,0,.22);
  opacity:0;
  pointer-events:none;
  transition:opacity .12s var(--ease-out);
}
.dock__item:hover::before{ opacity:1; }

/* ──────────────────────── folder windows ────────────────────────
   One per open folder, stacked and dragged independently. They share a
   shell and nothing else: a drag strip across the top with the three
   lights on it, a second full-bleed strip beneath the pages so a window
   can also be picked up anywhere its writing does not cover, and pages
   that scale with whatever the window is made of.                     */

.win{
  position:absolute;
  left:50%;
  top:47%;
  translate:-50% -50%;
  animation:win-in .19s var(--ease-out);
}
.win[hidden]{ display:none; }

@keyframes win-in{ from{ opacity:0; scale:.965; } }

.win__body{ position:absolute; inset:0; z-index:1; }

.win__grab{
  position:absolute;
  top:0; left:0; right:0;
  height:36px;
  z-index:3;
  user-select:none;
}

.win__lights{
  position:absolute;
  top:12px;
  left:14px;
  z-index:4;
  display:flex;
  gap:8px;
}

.win__light{
  width:12px;
  height:12px;
  padding:0;
  border:0;
  border-radius:50%;
  box-shadow:0 0 0 .5px rgba(0,0,0,.16) inset;
}
.win__light--close{ background:#FF5F57; }
.win__light--min  { background:#FEBC2E; }
.win__light--zoom { background:#28C840; }
.win__light:hover { filter:brightness(.92); }

/* an unfocused window greys its lights out, the way macOS does */
.win:not(.is-front) .win__light{ background:#D6D2C8; }

.win__page{
  position:relative;
  z-index:2;
  border:0;
  outline:none;
  resize:none;
  background:transparent;
}

/* ── Musings: a notebook ─────────────────────────────────────────
   Bare paper — no title bar, just the lights on the top-left corner. */

.win--nb{
  width:min(760px, 92vw);
  height:min(490px, 74vh);
  display:flex;
  border-radius:14px;
  overflow:hidden;
  background:#FBF9F4;
  box-shadow:
    0 1px 1px rgba(0,0,0,.10),
    0 20px 44px rgba(20,30,45,.28),
    0 50px 100px rgba(20,30,45,.22),
    0 0 0 .5px rgba(0,0,0,.13);
}

.win--nb.is-dragging{
  box-shadow:
    0 1px 1px rgba(0,0,0,.10),
    0 34px 66px rgba(20,30,45,.34),
    0 74px 130px rgba(20,30,45,.26),
    0 0 0 .5px rgba(0,0,0,.13);
}

.win--nb.is-zoomed{
  width:min(1080px, 96vw);
  height:min(720px, 88vh);
}

.nb__spread{
  position:relative;
  z-index:2;
  flex:1 1 auto;
  display:flex;
  min-height:0;
}

.nb__page{
  flex:1 1 50%;
  min-width:0;
  padding:40px 26px 24px;      /* top clears the light strip */
  font:14px/20px -apple-system, BlinkMacSystemFont, "SF Pro Text",
       "Inter", "Segoe UI", Helvetica, Arial, sans-serif;
  color:#33301f;
}
.nb__page::placeholder{ color:rgba(60,50,30,.22); }

/* left page stays bare paper; the grid lives only on the right */
.nb__page--grid{
  /* full-pixel rules: .5px lines alias into uneven weights as the page scales */
  background-image:
    repeating-linear-gradient(to right,  rgba(84,104,132,.17) 0 1px, transparent 1px 20px),
    repeating-linear-gradient(to bottom, rgba(84,104,132,.17) 0 1px, transparent 1px 20px);
  background-position:26px 40px;
}

/* the fold: a soft crease with a page edge either side. Transparent to the
   pointer, so the crease is somewhere you can pick the notebook up by. */
.nb__spine{
  flex:0 0 22px;
  pointer-events:none;
  background:
    linear-gradient(to right,
      rgba(90,74,40,0)   0%,
      rgba(90,74,40,.09) 32%,
      rgba(90,74,40,.22) 50%,
      rgba(90,74,40,.09) 68%,
      rgba(90,74,40,0)   100%),
    linear-gradient(to right, transparent 49%, rgba(90,74,40,.30) 50%, transparent 51%);
}

/* Side by side, two pages of a phone-width spread are ~160px each — too narrow
   to write on. Below that, open the notebook the other way: page over page. */
@media (max-width: 620px){
  .win--nb, .win--nb.is-zoomed{
    width:min(92vw, 430px);
    height:min(62vh, 520px);
  }
  .nb__spread{ flex-direction:column; }
  .nb__page{ flex:1 1 50%; padding:40px 18px 16px; }
  .nb__page--grid{ padding-top:16px; background-position:18px 16px; }

  .nb__spine{
    flex:0 0 18px;
    background:
      linear-gradient(to bottom,
        rgba(90,74,40,0)   0%,
        rgba(90,74,40,.09) 32%,
        rgba(90,74,40,.22) 50%,
        rgba(90,74,40,.09) 68%,
        rgba(90,74,40,0)   100%),
      linear-gradient(to bottom, transparent 49%, rgba(90,74,40,.30) 50%, transparent 51%);
  }
}

/* ── Developer: a tin, and Artist: a basket ──────────────────────
   Both are photographs with the studio backdrop keyed off, so the window
   *is* the object — no frame around it, and a drop-shadow rather than a
   box-shadow so the light falls through the basket's mesh.

   Their writing sits inside the object, pinned to the art in percentages.
   That only holds while the window keeps the photograph's aspect ratio, so
   height is the one thing set and width is derived from it — zooming moves
   `--h` and everything else follows.                                    */

.win--tin,
.win--basket{
  height:var(--h);
  background:center / 100% 100% no-repeat;
  filter:drop-shadow(0 14px 26px rgba(18,28,42,.40)) drop-shadow(0 2px 3px rgba(0,0,0,.22));
}

.win--tin.is-dragging,
.win--basket.is-dragging{
  filter:drop-shadow(0 26px 44px rgba(18,28,42,.46)) drop-shadow(0 3px 5px rgba(0,0,0,.24));
}

.win--tin{                                    /* 483 × 582 */
  --h:min(520px, 74vh, 86vw / 0.83);
  width:calc(var(--h) * 0.83);
  background-image:url("assets/objects/tin.webp");
}
.win--tin.is-zoomed{ --h:min(720px, 90vh, 92vw / 0.83); }

.win--basket{                                 /* 636 × 928 */
  --h:min(560px, 76vh, 78vw / 0.685);
  width:calc(var(--h) * 0.685);
  background-image:url("assets/objects/basket.webp");
}
.win--basket.is-zoomed{ --h:min(780px, 92vh, 88vw / 0.685); }

/* The lights ride the object rather than the window box: on the tin's lid,
   and on the pale handle across the top of the basket. */
.win--tin    .win__lights{ top:7.5%; left:15%; }
.win--basket .win__lights{ top:2.2%; left:29%; }

/* Both pans of the tin are writable — the open lid and the base below it.
   Monospaced, because of what this particular folder is called. */
.tin__page{
  position:absolute;
  left:13%;
  right:13%;
  padding:0;
  font:13px/18px ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  color:#333840;
}
.tin__page--lid { top:11%; height:31%; }
.tin__page--base{ top:57%; height:34%; }
.tin__page::placeholder{ color:rgba(40,46,56,.34); }

/* A card dropped in the basket. Inset well short of the walls — sized to the
   floor exactly, it covers the mesh that makes it read as a basket at all. */
.basket__page{
  position:absolute;
  left:22%;
  right:22%;
  top:26%;
  height:52%;
  padding:15px 16px;
  border-radius:3px;
  background:linear-gradient(180deg, #FFFDF6, #F9F1DF);
  box-shadow:0 1px 2px rgba(70,10,10,.34), 0 7px 16px rgba(50,6,6,.36);
  font:13.5px/20px -apple-system, BlinkMacSystemFont, "SF Pro Text",
       "Inter", "Segoe UI", Helvetica, Arial, sans-serif;
  color:#463526;
}
.basket__page::placeholder{ color:rgba(70,53,38,.30); }

/* ───────────────────────── open feedback ───────────────────────── */

@keyframes bounce{
  0%   { transform:translateY(0); }
  28%  { transform:translateY(-22px); }
  52%  { transform:translateY(0); }
  70%  { transform:translateY(-8px); }
  86%  { transform:translateY(0); }
  93%  { transform:translateY(-2.5px); }
  100% { transform:translateY(0); }
}

.dock__item.is-bouncing .dock__btn,
.icon.is-bouncing .icon__art{
  animation:bounce .78s var(--ease-out);
}

/* ─────────────────────── smaller screens ─────────────────────── */

@media (max-width: 760px){
  :root{ --dock-icon:46px; --dock-max:1.5; }
  .icons{ bottom:96px; }
  .icon{ width:102px; }   /* wide enough that "Photography" stays one line */
  .sticky{ width:min(84vw, 320px); height:min(46vh, 280px); }
  .menu[data-menu="go"],
  .menu[data-menu="window"],
  .menu[data-menu="help"],
  .menu[data-menu="view"]{ display:none; }
}

@media (max-width: 480px){
  :root{ --dock-icon:44px; }
  .icons{ bottom:88px; }
  .dock__list{ gap:2px; }
  .dock__sep{ margin:0 4px; }
  .status:not(.status--clock):not([title="Wi-Fi"]){ display:none; }
  /* the two most skippable apps, so the rest keep a usable tap target */
  .dock__item[data-label="Terminal"],
  .dock__item[data-label="System Settings"]{ display:none; }
}

@media (prefers-reduced-motion: reduce){
  *{ animation-duration:.001ms !important; transition-duration:.001ms !important; }
}
