/* =========================================================================
   juni-OS — retro desktop hub
   -------------------------------------------------------------------------
   THEMES live entirely in CSS custom properties below. Add a new theme by
   copying a [data-theme="..."] block — script.js already knows how to
   cycle through whatever list you give it (see THEMES array in script.js).
   ========================================================================= */

* { box-sizing: border-box; }

:root{
  --font-display: "Silkscreen", monospace;   /* true pixel headers & buttons */
  --font-body: "VT323", ui-monospace, monospace;        /* pixel-mono body text */
  --font-thin: "Micro 5", "VT323", monospace;   /* thinner pixel face for full blog posts */
  --radius: 16px;          /* rounded, cloud-like chrome (menubar/taskbar) */
  --dot: 4px;               /* dithered background dot spacing (mono theme only) */

  /* Pixel-stepped "staircase" corners, used instead of border-radius on window
     chrome for a subtly pixelated frame. --step controls how chunky the
     stairs look; scale it down (e.g. 4px) for small UI like buttons. */
  --step: 8px;
  --pixel-clip: polygon(
    0 var(--step), var(--step) var(--step), var(--step) 0,
    calc(100% - var(--step)) 0, calc(100% - var(--step)) var(--step), 100% var(--step),
    100% calc(100% - var(--step)), calc(100% - var(--step)) calc(100% - var(--step)), calc(100% - var(--step)) 100%,
    var(--step) 100%, var(--step) calc(100% - var(--step)), 0 calc(100% - var(--step))
  );
  --pixel-clip-top: polygon(
    0 var(--step), var(--step) var(--step), var(--step) 0,
    calc(100% - var(--step)) 0, calc(100% - var(--step)) var(--step), 100% var(--step),
    100% 100%, 0 100%
  );
  --step-sm: 4px;
  --pixel-clip-sm: polygon(
    0 var(--step-sm), var(--step-sm) var(--step-sm), var(--step-sm) 0,
    calc(100% - var(--step-sm)) 0, calc(100% - var(--step-sm)) var(--step-sm), 100% var(--step-sm),
    100% calc(100% - var(--step-sm)), calc(100% - var(--step-sm)) calc(100% - var(--step-sm)), calc(100% - var(--step-sm)) 100%,
    var(--step-sm) 100%, var(--step-sm) calc(100% - var(--step-sm)), 0 calc(100% - var(--step-sm))
  );

  /* Pixel-cat cursors — generated at runtime by updateCursors() in script.js
     so they're recoloured to match the active theme. These are just the
     pre-JS fallbacks. */
  --cursor-idle: auto;
  --cursor-point: pointer;

  /* Wallpaper dim overlay strength (0–0.9), set by the Desktop Settings
     app's dim slider — see setWallpaperDim() in script.js. */
  --wallpaper-dim: 0;
}

/* ---- theme: dreamy (default) — dusty mocha & pink, cloudy & sticker-y ---- */
[data-theme="dreamy"]{
  --bg:#2b201d; --paper:#3c2d29; --ink:#f7e9dc; --muted:#c99a8e; --accent:#ffb6c9; --accent-ink:#3c2117;
}
/* ---- theme: mono (matches the black & white paper look) ---- */
[data-theme="mono"]{
  --bg:#f3f3f0; --paper:#ffffff; --ink:#111111; --muted:#666666; --accent:#111111; --accent-ink:#ffffff;
}
/* ---- theme: dark ---- */
[data-theme="dark"]{
  --bg:#111214; --paper:#1b1c1f; --ink:#eaeaea; --muted:#9a9a9a; --accent:#7fffab; --accent-ink:#111214;
}
/* ---- theme: sepia ---- */
[data-theme="sepia"]{
  --bg:#f2e9d8; --paper:#fbf5e8; --ink:#2b1d0e; --muted:#7a6a4f; --accent:#b5651d; --accent-ink:#fff8ea;
}
/* ---- theme: pink ---- */
[data-theme="pink"]{
  --bg:#ffeaf4; --paper:#fff5fa; --ink:#3a1030; --muted:#8a5f7c; --accent:#ff5fa2; --accent-ink:#fff5fa;
}

html,body{ height:100%; }
body{
  margin:0;
  background-color:var(--bg);
  background-image: radial-gradient(var(--ink) 1px, transparent 1px);
  background-size: var(--dot) var(--dot);
  background-attachment: fixed;
  opacity: 1;
  color:var(--ink);
  font-family: var(--font-body);
  font-size:19px;
  transition: background-color .2s, color .2s;
  cursor: var(--cursor-idle);
}
/* the dreamy theme swaps the dot texture for the floating sticker layer */
[data-theme="dreamy"] body, body[data-theme="dreamy"]{ background-image:none; }
[data-theme="dreamy"]{ background-image:none; }

button, input, textarea, select{ font-family: inherit; font-size:16px; color:var(--ink); }
a{ color:var(--accent); text-decoration-thickness:2px; }

/* Pixel-cat "paw" cursor over anything clickable — see updateCursors() in
   script.js, which regenerates both cursors whenever the theme changes. */
a, button, .home-icon, .icon-btn, .track-row, .photo-tile, .taskbar-btn, .tv-channels button{
  cursor: var(--cursor-point);
}

/* ---------------------------- STICKER LAYER ------------------------------
   Fixed, non-interactive decorative critters that drift and bounce around
   the background. Populated + animated by script.js (see `STICKERS` array
   and animateStickers()). Purely cosmetic — hide it by clearing
   #sticker-field's innerHTML if you'd rather not use it. */
.sticker-field{
  position:fixed; inset:0; z-index:0; overflow:hidden; pointer-events:none;
  opacity:0; transition:opacity .2s;
}
[data-theme="dreamy"] .sticker-field{ opacity:.5; }
.sticker{
  position:absolute; top:0; left:0; will-change:transform;
  image-rendering:pixelated;
}

/* Emoji redrawn at low-res then scaled back up with no smoothing, so every
   icon in the UI reads as chunky pixel art instead of a smooth system emoji.
   Generated by pixelEmoji()/pixelIcon() in script.js. */
.pixel-emoji{ image-rendering:pixelated; vertical-align:middle; }

/* =========================== TOP MENU BAR =============================== */
#menubar{
  position:fixed; top:0; left:0; right:0; z-index:1000;
  display:flex; align-items:center; gap:16px;
  padding:10px 18px;
  background:var(--paper);
  border-bottom:3px solid var(--ink);
  box-shadow:0 3px 0 var(--muted);
}
.menu-logo{
  font-size:20px; background:none; border:none; cursor:pointer; color:var(--ink);
  transition:transform .15s;
}
.menu-logo:hover{ transform:rotate(-8deg) scale(1.1); }
.menu-title{
  font-family:var(--font-display); font-size:13px; color:var(--accent);
  white-space:nowrap;
}
.menu-links{ display:flex; gap:16px; flex:1; flex-wrap:wrap; }
.menu-links button, .menu-links a{
  background:none; border:none; cursor:pointer; text-decoration:none;
  font-family: var(--font-body); font-size:18px; letter-spacing:.3px; color:var(--ink);
}
.menu-links button:hover, .menu-links a:hover{ color:var(--accent); }
.menu-theme{
  margin-left:0; background:var(--bg); border:2px solid var(--ink); clip-path: var(--pixel-clip-sm);
  cursor:pointer; width:34px; height:34px; transition:transform .15s;
  display:flex; align-items:center; justify-content:center; padding:0;
}
.menu-theme:last-child{ margin-left:auto; }
.menu-theme:hover{ transform:rotate(20deg) scale(1.1); }

/* =============================== DESKTOP ================================= */
#desktop{
  position:relative;
  z-index:1;
  min-height:100vh;
  padding:70px 16px 60px;
  /* Custom wallpaper — set via the Desktop Settings app (setWallpaper() in
     script.js). Defaults to none, so the theme's plain background shows. */
  background-image: var(--wallpaper, none);
  background-size: cover;
  background-position: center;
  background-attachment: fixed;
}
body.has-wallpaper .sticker-field{ opacity:0; }

/* Dim overlay — a flat black layer whose opacity is driven by the Desktop
   Settings app's dim slider (--wallpaper-dim, 0 to 0.9). Sits above the
   wallpaper image but below the flicker overlay and all windows. */
#desktop::after{
  content:""; position:fixed; inset:0; z-index:1; pointer-events:none;
  background:#000; opacity:var(--wallpaper-dim, 0);
}

/* Retro TV effect toggle (Desktop Settings app) — a soft scanline flicker
   over the custom wallpaper. */
body.wallpaper-fx #desktop::before{
  content:""; position:fixed; inset:0; z-index:2; pointer-events:none;
  background: repeating-linear-gradient(0deg, rgba(0,0,0,.16) 0 2px, transparent 2px 4px);
  animation: tv-flicker .15s steps(2) infinite;
}
@keyframes tv-flicker{ 50%{ opacity:.8; } }

/* ================================ WINDOWS ================================ */
.window{
  position:absolute;
  min-width:260px;
  max-width:94vw;
  max-height: calc(100vh - 150px); /* leaves room for the fixed menubar + taskbar; window-body scrolls past this */
  background:var(--paper);
  border:3px solid var(--ink);
  clip-path: var(--pixel-clip);            /* pixel-stepped "staircase" frame */
  filter: drop-shadow(5px 5px 0 var(--ink)); /* follows the clipped shape, unlike box-shadow */
  resize:both;
  overflow:hidden;
  display:flex;
  flex-direction:column;
}
.window.active{ filter: drop-shadow(5px 5px 0 var(--accent)); }
.window.minimized{ display:none; }

.titlebar{
  position:relative;
  display:flex; align-items:center; gap:8px;
  padding:8px 10px;
  border-bottom:3px solid var(--ink);
  clip-path: var(--pixel-clip-top);        /* pixel-stepped top corners only */
  cursor:grab;
  user-select:none;
  background:linear-gradient(180deg, color-mix(in srgb, var(--accent) 35%, var(--paper)), var(--paper));
  flex:0 0 auto;
}
.titlebar:active{ cursor:grabbing; }
/* ricrac trim between titlebar and body — a small zigzag "ribbon" strip */
.ricrac{
  height:7px; flex:0 0 auto;
  background:
    linear-gradient(135deg, var(--paper) 25%, transparent 25%) 0 0,
    linear-gradient(225deg, var(--paper) 25%, transparent 25%) 0 0,
    var(--accent);
  background-size: 7px 7px;
}
.hatch{
  flex:1; height:2px;
  background: repeating-linear-gradient(90deg, var(--muted) 0 4px, transparent 4px 8px);
  border-radius:2px;
}
.win-title{
  font-family: var(--font-display); font-size:12px; white-space:nowrap;
  letter-spacing:.3px;
}
.icon-btn{
  flex:0 0 auto; width:22px; height:22px;
  clip-path: var(--pixel-clip-sm);
  border:2px solid var(--ink); background:var(--paper);
  display:flex; align-items:center; justify-content:center;
  font-size:10px; line-height:1; cursor:pointer; padding:0;
  transition:transform .12s;
}
.icon-btn:hover{ background:var(--accent); color:var(--accent-ink); transform:scale(1.12); }

.window-body{
  padding:16px 18px;
  overflow:auto;
  flex:1 1 auto;
  /* faint scanline texture for a bit more retro richness, kept subtle */
  background-image: repeating-linear-gradient(0deg, transparent 0 3px, rgba(0,0,0,.025) 3px 4px);
}
.window-body h2, .window-body h3{ font-family:var(--font-display); font-size:14px; line-height:1.7; color:var(--accent); }
.window-body p, .window-body li{ line-height:1.45; }

/* =============================== TASKBAR ================================= */
#taskbar{
  position:fixed; bottom:0; left:0; right:0; z-index:1000;
  display:flex; gap:8px; align-items:center;
  padding:8px 12px;
  background:var(--paper);
  border-top:3px solid var(--ink);
  overflow-x:auto;
}
.taskbar-btn{
  font-family: var(--font-body); font-size:15px;
  border:2px solid var(--ink); clip-path: var(--pixel-clip-sm); background:var(--bg); color:var(--ink);
  padding:6px 14px; cursor:pointer; white-space:nowrap; flex:0 0 auto;
}
.taskbar-btn.active{ background:var(--accent); color:var(--accent-ink); }

/* ============================ HOME CARD GRID ============================= */
.home-grid{
  display:grid; grid-template-columns:repeat(4, 1fr); gap:18px 10px;
  text-align:center;
}
.home-icon{
  display:flex; flex-direction:column; align-items:center; gap:6px;
  background:none; border:none; cursor:pointer; color:var(--ink);
}
.home-icon-glyph{
  font-size:28px; transition: transform .15s;
  width:44px; height:44px; display:flex; align-items:center; justify-content:center;
  background:var(--bg); border:2px solid var(--ink); clip-path: var(--pixel-clip-sm);
}
.home-icon-label{ font-family: var(--font-body); font-size:15px; }
.home-icon:hover .home-icon-glyph{ transform:translateY(-3px) rotate(-6deg); background:var(--accent); }
.home-pager{
  display:flex; align-items:center; justify-content:center; gap:14px; margin-top:16px;
}

/* ============================= REUSABLE BITS ============================= */
.field{ display:flex; flex-direction:column; gap:4px; margin-bottom:10px; }
.field input, .field textarea{
  border:2px solid var(--ink); clip-path: var(--pixel-clip-sm); background:var(--bg); padding:8px 10px; resize:vertical;
}
.btn{
  font-family: var(--font-display); font-size:11px;
  border:2px solid var(--ink); clip-path: var(--pixel-clip-sm); background:var(--accent); color:var(--accent-ink);
  padding:9px 16px; cursor:pointer; transition:transform .12s;
}
.btn:hover{ transform:translateY(-2px) scale(1.03); }
.tag{
  display:inline-block; font-size:13px; border:1px solid var(--ink); clip-path: var(--pixel-clip-sm);
  padding:1px 8px; margin-right:6px; font-family:var(--font-body); background:var(--bg);
}
.card{
  border:2px dashed var(--muted); clip-path: var(--pixel-clip-sm); padding:10px 14px; margin-bottom:10px;
  overflow-wrap:anywhere; word-break:break-word; /* keep long unbroken text from overflowing the card */
}
.card p{ margin:6px 0 0; white-space:pre-wrap; } /* wrap normally + respect line breaks the user typed */
.meta{ color:var(--muted); font-size:14px; }
.divider{ border:none; border-top:2px dashed var(--muted); margin:14px 0; position:relative; }
.divider::after{
  content:"♡"; position:absolute; top:-11px; left:50%; transform:translateX(-50%);
  background:var(--paper); padding:0 8px; color:var(--accent);
}

/* full blog post window — thinner pixel font + optional header image.
   Covers everything parseMarkdown() in script.js can produce, plus raw
   HTML posts. */
.post-image{
  width:100%; display:block; margin-bottom:12px;
  border:2px solid var(--ink); clip-path: var(--pixel-clip-sm);
}
.post-body{
  font-family: var(--font-thin); font-size:24px; line-height:1.5;
}
.post-body p{ margin:0 0 14px; overflow-wrap:anywhere; }
.post-body h2, .post-body h3, .post-body h4{ font-family:var(--font-display); color:var(--accent); margin:18px 0 10px; line-height:1.5; }
.post-body ul{ margin:0 0 14px; padding-left:26px; }
.post-body li{ margin-bottom:6px; }
.post-body blockquote{
  margin:0 0 14px; padding:4px 14px; border-left:4px solid var(--accent);
  color:var(--muted); font-style:italic;
}
.post-body blockquote p{ margin:0 0 6px; }
.post-body code{
  font-family:var(--font-body); background:var(--bg); border:1px solid var(--muted);
  padding:1px 5px; font-size:20px;
}
.post-inline-image{
  width:100%; display:block; margin:10px 0; border:2px solid var(--ink);
  clip-path: var(--pixel-clip-sm);
}

/* photo grid */
.photo-grid{ display:grid; grid-template-columns:repeat(3, 1fr); gap:8px; }
.photo-tile{
  aspect-ratio:1; border:2px solid var(--ink); clip-path: var(--pixel-clip-sm); cursor:pointer;
  display:flex; align-items:flex-end; padding:6px; font-size:13px;
  background:repeating-linear-gradient(45deg, var(--paper), var(--paper) 6px, var(--bg) 6px, var(--bg) 12px);
}
.photo-tile.large{ grid-column:1/-1; aspect-ratio:16/10; }

/* music player */
.player{ border:2px solid var(--ink); clip-path: var(--pixel-clip-sm); padding:12px; background:var(--bg); }
.track-row{
  display:flex; justify-content:space-between; align-items:center;
  padding:7px 6px; cursor:pointer; border-bottom:1px dashed var(--muted);
}
.track-row:hover{ background:var(--paper); }
.track-row.playing{ color:var(--accent); }
.player-controls{ display:flex; gap:10px; justify-content:center; margin:10px 0; }
.progress{ width:100%; accent-color:var(--accent); }

/* ================================ RETRO TV ================================ */
.tv{ background:var(--paper); border:3px solid var(--ink); clip-path: var(--pixel-clip); padding:14px; }
.tv-screen{
  position:relative; aspect-ratio:4/3; background:#0b0b0b; overflow:hidden;
  border:3px solid var(--ink); clip-path: var(--pixel-clip-sm);
}
.tv-screen::after{ /* scanline overlay, always on for CRT feel */
  content:""; position:absolute; inset:0; pointer-events:none;
  background: repeating-linear-gradient(0deg, rgba(0,0,0,.35) 0 2px, transparent 2px 4px);
}
.tv-static{
  position:absolute; inset:0;
  background: repeating-linear-gradient(0deg, #999 0 2px, #222 2px 4px);
  animation: staticflicker .12s steps(2) infinite;
}
@keyframes staticflicker{ 50%{ transform:translateY(2px); filter:brightness(1.15); } }
.tv-iframe{ width:100%; height:100%; border:0; }
.tv-controls{ display:flex; align-items:center; gap:10px; margin-top:10px; flex-wrap:wrap; }
.tv-channels{ display:flex; gap:6px; }
.tv-channels .btn{ padding:6px 10px; }
.tv-channels .btn.on{ background:var(--ink); color:var(--paper); }

/* ================================= NEKO ==================================
   A little pixel cat that chases the mouse cursor. Spawned/despawned from
   the Neko app (see toggleNeko() in script.js). Position is driven entirely
   by JS (translate transform each frame); CSS only handles the idle bob. */
.neko{
  position:fixed; top:0; left:0; width:32px; height:32px;
  z-index:2000; pointer-events:none; will-change:transform;
}
.neko-sprite{
  width:100%; height:100%; background-size:contain; background-repeat:no-repeat;
  image-rendering:pixelated;
}
.neko.idle .neko-sprite{ animation: neko-bob 1.2s ease-in-out infinite; }
@keyframes neko-bob{ 50%{ transform:translateY(-2px); } }

/* =============================== MOBILE =================================== */
@media (max-width: 720px){
  .home-grid{ grid-template-columns:repeat(3, 1fr); }
  .photo-grid{ grid-template-columns:repeat(2, 1fr); }
  .menu-links{ gap:10px; }

  /* On small screens windows stack in normal flow instead of free dragging —
     much friendlier for touch than absolute-positioned draggable boxes. */
  #desktop.stacked{ display:flex; flex-direction:column; gap:14px; }
  #desktop.stacked .window{
    position:static !important; width:100% !important; height:auto !important; max-height:none !important;
    max-width:100%; resize:none; filter:none; box-shadow:4px 4px 0 var(--ink);
  }
  #desktop.stacked .window.minimized{ display:none; }
  #desktop.stacked .titlebar{ cursor:default; }
}
