/* Shared dark/green theme for Word Pull, Quickwrite, Reflection, Vocab, About.
   Include after: <link href="...Playfair+Display..." rel="stylesheet"> */

:root{
  --bg: #0a0a0b;
  --border: #232427;
  --text: #f3f3f2;
  --muted: #6c6f73;
  --dim: #3a3c3f;
  /* the site's single accent color, as an r,g,b triplet so it can be reused
     at any opacity via rgba(var(--accent-rgb), X) -- everything below this
     point that reads "green" is really just "the accent," it's named --green
     for historical/readability reasons but it follows whatever's picked on
     the Colors page (data-accent on <html>, saved to localStorage) */
  --accent-rgb: 62,207,126;
  --green: rgb(var(--accent-rgb));
  --green-soft: rgba(var(--accent-rgb),0.45);
}
/* ---------- no-JS fallback ----------
   body.pre-materialize is only ever removed by transitions.js on load, so
   without JS the .stage stays permanently blurred/invisible -- this message
   lives outside .stage entirely, as a fixed full-screen overlay, so it's
   the one thing guaranteed to actually show up in that situation. */
.noscript-msg{
  position:fixed;
  inset:0;
  z-index:20000;
  display:flex;
  align-items:center;
  justify-content:center;
  text-align:center;
  padding:32px;
  background:var(--bg);
  color:var(--text);
  font-family:Georgia, 'Playfair Display', serif;
  font-size:16px;
  line-height:1.6;
}

/* accent palette -- selected on colors.html, applied by setting data-accent
   on <html> (an inline blocking script in <head> does this before first
   paint on every page, reading the same localStorage key, so there's no
   flash of the default green before the saved color kicks in) */
html[data-accent="blue"]    { --accent-rgb: 74,158,255; }
html[data-accent="purple"]  { --accent-rgb: 168,124,255; }
html[data-accent="red"]     { --accent-rgb: 230,57,53; }
html[data-accent="gold"]    { --accent-rgb: 232,180,64; }
html[data-accent="rose"]    { --accent-rgb: 255,120,170; }
html[data-accent="cyan"]    { --accent-rgb: 70,214,214; }
html[data-accent="magenta"] { --accent-rgb: 214,64,201; }
*{box-sizing:border-box;}
html{
  /* always reserve the scrollbar's space (rather than auto-hiding it) so
     the centered nav never shifts sideways between a short page and a tall
     one -- but style it as a thin, faint gray track instead of the bulky
     default OS scrollbar, matching the same thin-scrollbar treatment used
     on #historyList/#poemText/.view-text elsewhere in the site. */
  overflow-y:scroll;
  scrollbar-width:thin;              /* Firefox */
  scrollbar-color:var(--border) transparent;
}
html::-webkit-scrollbar{ width:6px; }               /* Chrome, Safari, new Edge */
html::-webkit-scrollbar-track{ background:transparent; }
html::-webkit-scrollbar-thumb{ background:var(--border); border-radius:6px; }
html,body{
  margin:0;
  min-height:100vh;
  background:var(--bg);
  font-family:-apple-system, BlinkMacSystemFont, 'Inter', 'Segoe UI', sans-serif;
  color:var(--text);
  overflow-x:hidden;
}
body{
  display:flex;
  align-items:flex-start;
  justify-content:center;
  padding:112px 16px 48px;
  position:relative;
}

/* ---------- ambient background words ---------- */
/* kept above the transition overlays on purpose: the ambient words should
   never be covered or paused, only the foreground changes. .site-nav (below)
   is pinned even higher for the same reason -- it never moves either, so it
   should never be masked by the morph-box/page-enter-overlay mid-transition */
#bgWords{
  position:fixed;
  inset:0;
  overflow:hidden;
  pointer-events:none;
  z-index:10000;
  /* clear a calm hole in the middle of the viewport (where the actual
     content/buttons live) so the word field reads as atmosphere around the
     edges rather than clutter competing with what you're trying to read --
     aiming for "inviting and sleek" instead of a dense word-cloud */
  -webkit-mask-image:radial-gradient(circle at center, transparent 0%, transparent 25%, #000 60%);
  mask-image:radial-gradient(circle at center, transparent 0%, transparent 25%, #000 60%);
}
.bg-word{
  position:absolute;
  white-space:nowrap;
  font-weight:600;
  color:var(--text);
  opacity:0.05;
  filter:blur(0.2px);
  animation:drift linear infinite;
}
.bg-word.accent{ color:var(--green); }
@keyframes drift{
  0%   { transform:translateY(0) translateX(0); }
  50%  { transform:translateY(-26px) translateX(10px); }
  100% { transform:translateY(0) translateX(0); }
}

/* ---------- stage / shared layout ---------- */
.stage{
  position:relative;
  z-index:1;
  width:100%;
  max-width:760px;
  text-align:center;
}
.label-row{
  position:relative;
  display:flex;
  align-items:center;
  justify-content:center;
  gap:16px;
  margin-bottom:22px;
  font-size:27px;
  letter-spacing:2px;
  text-transform:uppercase;
  color:var(--text);
  font-weight:600;
}
.label-row b{
  color:var(--green);
  font-weight:600;
}

/* the home page wordmark ("Word Pull") is emphasized as a proper title
   rather than reusing the small-caps section-label look every sub-page uses */
.brand-title{
  font-family:'Playfair Display', Georgia, 'Times New Roman', serif;
  font-size:42px;
  font-weight:700;
  letter-spacing:0.3px;
  text-transform:none;
}
.dot{
  width:4px;height:4px;
  border-radius:50%;
  background:var(--muted);
}

/* ---------- nav / hub ---------- */
.site-nav{
  position:fixed;
  top:0;
  left:0;
  right:0;
  height:76px;
  /* same tier as #bgWords: fixed chrome that never moves, so it should
     never be covered/masked by the morph-box or page-enter-overlay either */
  z-index:10001;
  display:flex;
  align-items:center;
  justify-content:center;
  gap:34px;
  font-size:12px;
  letter-spacing:2px;
  text-transform:uppercase;
  background:linear-gradient(to bottom, var(--bg) 0%, var(--bg) 62%, rgba(10,10,11,0) 100%);
}
.site-nav a{
  color:var(--muted);
  text-decoration:none;
  transition:color 0.15s ease;
}
.site-nav a:hover,
.site-nav a.active{
  color:var(--green);
}
@media (max-width:600px){
  /* four nav items (Home/History/About/Colors) at the desktop gap/size
     would overflow a narrow phone screen -- shrink both a bit so they still
     fit on one line instead of getting clipped by body's overflow-x:hidden */
  .site-nav{ gap:18px; font-size:10.5px; letter-spacing:1.2px; }
}

/* ---------- reel (word pull) ---------- */
.reel-frame{
  position:relative;
}
.reel-window{
  position:relative;
  height:260px;
  overflow:hidden;
  -webkit-mask-image:linear-gradient(180deg, transparent 0%, #000 28%, #000 72%, transparent 100%);
  mask-image:linear-gradient(180deg, transparent 0%, #000 28%, #000 72%, transparent 100%);
}
.reel-track{
  position:relative;
  top:0;
  will-change:transform;
}
.reel-item{
  height:130px;
  /* pin the line box to the item's own height (instead of the font-metric-
     dependent "normal" line-height) so the text's vertical center stays
     locked to the item's true center no matter how big font-size grows --
     this is what keeps the settled word dead-center between the two tick
     lines as it expands, rather than drifting with font ascent/descent */
  line-height:130px;
  display:flex;
  align-items:center;
  justify-content:center;
  font-family:'Playfair Display', Georgia, 'Times New Roman', serif;
  font-size:38px;
  font-weight:500;
  letter-spacing:2px;
  color:var(--dim);
  transition:font-size 0.4s cubic-bezier(0.2,0.8,0.2,1), color 0.4s ease, letter-spacing 0.4s ease, text-shadow 0.4s ease;
  /* Playfair Display's own ascent/descent metrics aren't split 50/50, so
     even with line-height exactly matching the box, the glyphs themselves
     sit visually a little low within it (more room above than below). This
     is a small optical correction, in em units so it scales with font-size
     across the small/spinning state and the big/settled state alike. */
  transform:translateY(-0.05em);
}
.reel-item.is-center{
  color:var(--text);
  font-size:96px;
  font-weight:600;
  letter-spacing:1px;
  text-shadow:0 14px 34px rgba(0,0,0,0.55);
}
.reel-item.placeholder{
  color:var(--dim);
  font-size:34px;
  font-weight:500;
  font-style:italic;
  letter-spacing:2px;
  /* match .reel-window's height so the single placeholder item centers
     itself vertically (via the flex centering already on .reel-item)
     instead of sitting pinned to the top of the window like the 130px
     spin-items do */
  height:260px;
}
.tick{
  position:absolute;
  left:50%;
  width:170px;
  height:1px;
  background:var(--green);
  transform:translateX(-50%);
}
.tick.top{ top:calc(50% - 84px); }
.tick.bottom{ bottom:calc(50% - 84px); }

/* ---------- prompt card (quickwrite prompt mode / reflection) ---------- */
.prompt-card{
  font-family:Georgia, 'Times New Roman', serif;
  font-style:italic;
  font-size:30px;
  line-height:1.5;
  color:var(--text);
  max-width:640px;
  margin:20px auto;
  min-height:120px;
  display:flex;
  align-items:center;
  justify-content:center;
}
.prompt-choices{
  display:flex;
  flex-direction:column;
  gap:14px;
  max-width:600px;
  margin:0 auto;
}

/* ---------- quickwrite random prompt: letters pop in one by one instead of
   the whole sentence appearing at once ---------- */
.prompt-card .pc-inner{ display:inline; }
.prompt-card .pc-word{ display:inline-block; }
.prompt-card .pc-char{
  display:inline-block;
  opacity:0;
  transform:scale(0.35) translateY(8px);
  animation:charPopIn 0.4s cubic-bezier(0.34,1.56,0.64,1) forwards;
}
@keyframes charPopIn{
  to{ opacity:1; transform:scale(1) translateY(0); }
}
.prompt-choice{
  padding:18px 22px;
  border:1px solid var(--border);
  border-radius:14px;
  background:transparent;
  color:var(--text);
  font-family:Georgia, 'Times New Roman', serif;
  font-style:italic;
  font-size:18px;
  line-height:1.5;
  text-align:left;
  cursor:pointer;
  transition:border-color 0.15s ease, background 0.15s ease, transform 0.18s cubic-bezier(0.2,0.8,0.2,1);
}
.prompt-choice:hover:not(:disabled){
  border-color:var(--green-soft);
  background:rgba(var(--accent-rgb),0.06);
  transform:scale(1.025);
}

/* ---------- reflection shuffle: old cards slide out right, new cards slide
   in from the left, instead of just swapping instantly ---------- */
.prompt-choice.shuffle-anim{
  transition:
    transform 0.42s cubic-bezier(0.22,0.85,0.16,1),
    opacity 0.36s ease,
    border-color 0.15s ease,
    background 0.15s ease;
}
.prompt-choice.shuffle-anim.sliding-out{
  transform:translateX(120%);
  opacity:0;
}
.prompt-choice.shuffle-anim.sliding-in{
  transform:translateX(-120%);
  opacity:0;
}

/* ---------- mode toggle / segmented control ---------- */
.mode-toggle,
.duration-toggle{
  display:flex;
  justify-content:center;
  gap:10px;
  margin-bottom:26px;
  flex-wrap:wrap;
}
.toggle-btn{
  padding:9px 20px;
  font-size:12px;
  letter-spacing:2px;
  text-transform:uppercase;
  font-weight:600;
  color:var(--muted);
  background:transparent;
  border:1px solid var(--border);
  border-radius:30px;
  cursor:pointer;
  transition:color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.toggle-btn:hover{
  color:var(--text);
  border-color:var(--dim);
}
.toggle-btn.active{
  color:var(--green);
  border-color:var(--green);
  background:rgba(var(--accent-rgb),0.08);
}

/* ---------- buttons ---------- */
.actions{
  display:flex;
  justify-content:center;
  gap:14px;
  margin-top:34px;
  flex-wrap:wrap;
}
.pull-button{
  display:inline-block;
  padding:15px 50px;
  font-size:14px;
  letter-spacing:4px;
  font-weight:600;
  text-transform:uppercase;
  text-decoration:none;
  color:var(--green);
  background:transparent;
  border:1px solid var(--green);
  border-radius:40px;
  cursor:pointer;
  transition:background 0.15s ease, color 0.15s ease, transform 0.08s ease;
}
.pull-button:hover{
  background:var(--green);
  color:#0a0a0b;
}
.pull-button:active{
  transform:translateY(1px);
}
.pull-button:disabled{
  opacity:0.35;
  cursor:default;
  background:transparent;
  color:var(--green);
}
.pull-button.secondary{
  color:var(--muted);
  border-color:var(--border);
}
.pull-button.secondary:hover{
  background:transparent;
  color:var(--text);
  border-color:var(--dim);
}
.result-note{
  text-align:center;
  margin-top:20px;
  min-height:20px;
  font-size:14px;
  color:var(--muted);
  letter-spacing:0.3px;
}

/* ---------- history ---------- */
.history-wrap{
  margin-top:56px;
  padding-top:20px;
  border-top:1px solid var(--border);
}
.history-head{
  display:flex;
  align-items:center;
  justify-content:space-between;
  margin-bottom:12px;
}
.history-head span{
  font-size:12px;
  letter-spacing:3px;
  text-transform:uppercase;
  color:var(--muted);
}
.history-head button{
  background:none;
  border:none;
  color:var(--muted);
  font-size:12px;
  letter-spacing:1px;
  cursor:pointer;
  text-decoration:underline;
  text-underline-offset:3px;
}
.history-head button:hover{
  color:var(--green);
}
#historyList{
  list-style:none;
  margin:0;
  padding:0;
  max-height:220px;
  overflow-y:auto;
  text-align:left;
  scrollbar-width:thin;
  scrollbar-color:var(--border) transparent;
}
#historyList li{
  display:flex;
  align-items:baseline;
  gap:16px;
  padding:10px 2px;
  font-size:16px;
  border-bottom:1px solid var(--border);
  color:var(--text);
  cursor:pointer;
}
#historyList li:last-child{border-bottom:none;}
#historyList li:hover .h-word{ color:var(--green); }
#historyList .h-tag{
  color:var(--green);
  font-size:11px;
  font-weight:600;
  letter-spacing:1px;
  text-transform:uppercase;
  min-width:64px;
}
#historyList .h-word{
  flex:1;
  font-weight:500;
  letter-spacing:1px;
}
#historyList .h-date{
  color:var(--muted);
  font-size:12px;
}
#historyList::-webkit-scrollbar{width:6px;}
#historyList::-webkit-scrollbar-thumb{background:var(--border);border-radius:6px;}
.empty-note{
  color:var(--muted);
  font-size:14px;
  text-align:center;
  padding:6px 0;
}
.storage-note{
  color:var(--muted);
  font-size:12px;
  letter-spacing:0.3px;
  text-align:center;
  margin-top:10px;
  opacity:0.75;
}

@media (max-width:600px){
  .reel-window{ height:180px; }
  .reel-item{ height:90px; line-height:90px; font-size:24px; letter-spacing:1px; }
  .reel-item.is-center{ font-size:56px; }
  .reel-item.placeholder{ height:180px; }
  .tick{ width:100px; }
  .tick.top{ top:calc(50% - 58px); }
  .tick.bottom{ bottom:calc(50% - 58px); }
  .label-row{ font-size:20px; letter-spacing:1.5px; }
  .brand-title{ font-size:30px; }
  .prompt-card{ font-size:22px; }
}

.timer-btn{ margin-left:14px; }

/* ---------- write overlay ---------- */
.write-overlay{
  position:fixed;
  inset:0;
  z-index:20;
  background:var(--bg);
  display:flex;
  flex-direction:column;
  align-items:center;
  padding:56px 24px 40px;
  opacity:0;
  pointer-events:none;
  transition:opacity 0.3s ease;
}
.write-overlay.active{
  opacity:1;
  pointer-events:all;
}
.write-head{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:10px;
  margin-bottom:30px;
  max-width:680px;
}
.write-word{
  font-family:'Playfair Display', Georgia, serif;
  font-size:34px;
  font-weight:600;
  color:var(--text);
  letter-spacing:1px;
}
.write-prompt{
  font-family:Georgia, 'Times New Roman', serif;
  font-style:italic;
  font-size:22px;
  line-height:1.5;
  color:var(--text);
  text-align:center;
}
.timer-display{
  font-size:34px;
  font-weight:600;
  letter-spacing:2px;
  color:var(--green);
  font-variant-numeric:tabular-nums;
}
.timer-display.done{
  color:var(--green);
  animation:timesUpPulse 1.3s ease-in-out infinite;
}
@keyframes timesUpPulse{
  0%, 100%{ opacity:1; }
  50%{ opacity:0.3; }
}
#poemText{
  flex:1;
  width:100%;
  max-width:680px;
  background:transparent;
  border:none;
  outline:none;
  resize:none;
  color:var(--text);
  font-family:Georgia, 'Times New Roman', serif;
  font-size:20px;
  line-height:1.8;
  scrollbar-width:thin;
  scrollbar-color:var(--border) transparent;
}
#poemText::-webkit-scrollbar{ width:8px; }
#poemText::-webkit-scrollbar-track{ background:transparent; }
#poemText::-webkit-scrollbar-thumb{
  background:var(--border);
  border-radius:8px;
}
#poemText::-webkit-scrollbar-thumb:hover{
  background:var(--dim);
}
#poemText::placeholder{
  color:var(--dim);
}
.write-actions{
  display:flex;
  gap:14px;
  margin-top:24px;
}

/* ---------- zen mode: the write-overlay markup reused as a standalone,
   always-on page with no header/word/prompt above the textarea, so give it
   a bit more breathing room at the top instead of the gap a write-head
   would normally occupy ---------- */
.zen-overlay{
  padding-top:120px;
}
@media (max-width:600px){
  .zen-overlay{ padding-top:80px; }
}
.close-link{
  background:none;
  border:none;
  color:var(--muted);
  font-size:13px;
  letter-spacing:1px;
  cursor:pointer;
  text-decoration:underline;
  text-underline-offset:3px;
}
.close-link:hover{ color:var(--text); }

.copy-btn{
  position:absolute;
  top:22px;
  right:28px;
  background:none;
  border:1px solid var(--border);
  color:var(--muted);
  font-size:11px;
  letter-spacing:1.5px;
  text-transform:uppercase;
  padding:5px 12px;
  border-radius:20px;
  cursor:pointer;
  opacity:0.55;
  transition:opacity 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.copy-btn:hover{
  opacity:1;
  color:var(--green);
  border-color:var(--green-soft);
}

/* ---------- read-only history entry viewer ---------- */
/* clicking a saved history entry opens this instead of doing nothing */
.view-overlay{
  position:fixed;
  inset:0;
  z-index:20;
  background:var(--bg);
  display:flex;
  flex-direction:column;
  align-items:center;
  padding:56px 24px 40px;
  opacity:0;
  pointer-events:none;
  transition:opacity 0.3s ease;
}
.view-overlay.active{
  opacity:1;
  pointer-events:all;
}
.view-meta{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:8px;
  margin-bottom:26px;
  max-width:680px;
  text-align:center;
}
.view-tag{
  font-size:12px;
  letter-spacing:2px;
  text-transform:uppercase;
  color:var(--green);
  font-weight:600;
}
.view-prompt{
  font-family:Georgia, 'Times New Roman', serif;
  font-style:italic;
  font-size:22px;
  line-height:1.5;
  color:var(--text);
}
.view-date{
  font-size:12px;
  color:var(--muted);
  letter-spacing:0.5px;
}
.view-text{
  flex:1;
  width:100%;
  max-width:680px;
  overflow-y:auto;
  color:var(--text);
  font-family:Georgia, 'Times New Roman', serif;
  font-size:20px;
  line-height:1.8;
  white-space:pre-wrap;
  scrollbar-width:thin;
  scrollbar-color:var(--border) transparent;
  /* a <textarea> so Edit mode can unlock it in place, but reset to look
     like plain text while read-only */
  background:transparent;
  border:none;
  outline:none;
  resize:none;
  box-sizing:border-box;
  padding:0;
}
.view-text::-webkit-scrollbar{ width:8px; }
.view-text::-webkit-scrollbar-track{ background:transparent; }
.view-text::-webkit-scrollbar-thumb{
  background:var(--border);
  border-radius:8px;
}

/* ---------- definition ---------- */
.definition{
  margin-top:14px;
  min-height:52px;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:9px;
  opacity:0;
  transform:translateY(-6px);
  transition:opacity 0.4s ease, transform 0.4s ease;
}
.definition.visible{
  opacity:1;
  transform:translateY(0);
}
.pos-badge{
  display:inline-block;
  padding:5px 16px;
  border-radius:20px;
  font-size:14px;
  font-weight:700;
  letter-spacing:2px;
  text-transform:uppercase;
  background:rgba(255,255,255,0.08);
  color:var(--muted);
}
.pos-badge.pos-noun{ background:rgba(90,169,255,0.15); color:#5aa9ff; }
.pos-badge.pos-verb{ background:rgba(255,159,67,0.15); color:#ff9f43; }
.pos-badge.pos-adjective{ background:rgba(190,120,255,0.15); color:#be78ff; }
.pos-badge.pos-adverb{ background:rgba(255,120,180,0.15); color:#ff78b4; }
.def-text{
  font-family:Georgia, 'Times New Roman', serif;
  font-style:italic;
  font-size:21px;
  color:#c9c6bd;
  max-width:560px;
  line-height:1.5;
}

/* ---------- vocab game ---------- */
.vocab-score{
  display:flex;
  justify-content:center;
  gap:28px;
  margin-bottom:8px;
  font-size:13px;
  letter-spacing:1px;
  text-transform:uppercase;
  color:var(--muted);
}
.vocab-score b{
  color:var(--green);
  font-size:16px;
  letter-spacing:0;
}
.vocab-word{
  font-family:'Playfair Display', Georgia, serif;
  font-size:56px;
  font-weight:600;
  color:var(--text);
  letter-spacing:1px;
  margin:18px 0 6px;
}
.vocab-feedback{
  min-height:24px;
  font-size:14px;
  letter-spacing:0.5px;
  margin-top:16px;
}
.vocab-feedback.correct{ color:var(--green); }
.vocab-feedback.wrong{ color:#ff7a7a; }
.prompt-choice.correct{
  border-color:var(--green);
  background:rgba(var(--accent-rgb),0.1);
  color:var(--green);
}
.prompt-choice.wrong{
  border-color:#ff7a7a;
  background:rgba(255,122,122,0.08);
  color:#ff9d9d;
}
.prompt-choice:disabled{
  cursor:default;
}

/* ---------- about page ---------- */
.about-card{
  text-align:center;
  max-width:520px;
  margin:0 auto;
}
.about-card p{
  font-family:Georgia, 'Times New Roman', serif;
  font-size:18px;
  line-height:1.7;
  color:var(--text);
}
.about-links{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:14px;
  margin-top:30px;
}
@media (max-width:480px){
  .about-links{ grid-template-columns:1fr; }
}
.about-links a{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:10px;
  color:var(--text);
  text-decoration:none;
  font-size:14px;
  letter-spacing:1px;
  border:1px solid var(--border);
  border-radius:30px;
  padding:12px 20px;
  transition:color 0.15s ease, border-color 0.15s ease;
}
.about-links a:hover{
  color:var(--green);
  border-color:var(--green-soft);
}
.about-links .icon{
  width:18px;
  height:18px;
  flex-shrink:0;
}

/* ---------- colors page (accent picker) ---------- */
.swatch-grid{
  display:grid;
  grid-template-columns:repeat(4, 1fr);
  gap:20px;
  max-width:460px;
  margin:36px auto 0;
}
@media (max-width:480px){
  .swatch-grid{ grid-template-columns:repeat(3, 1fr); }
}
.swatch-item{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:10px;
  background:none;
  border:none;
  cursor:pointer;
  padding:6px;
}
.swatch-dot{
  width:44px;
  height:44px;
  border-radius:50%;
  background:rgb(var(--swatch-rgb));
  border:2px solid transparent;
  box-shadow:0 4px 16px rgba(var(--swatch-rgb),0.35);
  transition:transform 0.15s cubic-bezier(0.2,0.8,0.2,1), border-color 0.15s ease;
}
.swatch-item:hover .swatch-dot{
  transform:scale(1.08);
}
.swatch-item.active .swatch-dot{
  border-color:var(--text);
}
.swatch-label{
  font-size:12px;
  letter-spacing:1px;
  color:var(--muted);
  transition:color 0.15s ease;
}
.swatch-item.active .swatch-label{
  color:var(--text);
}
.color-preview{
  margin-top:48px;
  padding-top:32px;
  border-top:1px solid var(--border);
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:22px;
}

/* ---------- hub cards (legacy, kept in case reused) ---------- */
.hub-grid{
  display:grid;
  grid-template-columns:repeat(2, 1fr);
  gap:18px;
  margin-top:36px;
}
@media (max-width:600px){
  .hub-grid{ grid-template-columns:1fr; }
}
.hub-card{
  display:block;
  padding:28px 22px;
  border:1px solid var(--border);
  border-radius:18px;
  text-decoration:none;
  text-align:left;
  transition:border-color 0.15s ease, transform 0.1s ease, background 0.15s ease;
}
.hub-card:hover{
  border-color:var(--green-soft);
  background:rgba(var(--accent-rgb),0.04);
  transform:translateY(-2px);
}
.hub-card h3{
  margin:0 0 8px;
  color:var(--text);
  font-size:19px;
  letter-spacing:0.5px;
}
.hub-card p{
  margin:0;
  color:var(--muted);
  font-size:14px;
  line-height:1.5;
}

/* ---------- launch row (index.html: Reflection / Quickwrite / Vocab) ---------- */
.launch-row{
  display:flex;
  gap:16px;
  margin-top:40px;
  align-items:flex-start;
}
@media (max-width:640px){
  .launch-row{ flex-direction:column; }
}
.launch-btn{
  flex:1;
  aspect-ratio:1 / 1;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:14px;
  padding:20px;
  border:1px solid var(--border);
  border-radius:24px;
  text-decoration:none;
  box-sizing:border-box;
  text-align:center;
  transition:border-color 0.18s ease, transform 0.12s ease, background 0.18s ease;
}
.launch-btn:hover{
  border-color:var(--green-soft);
  background:rgba(var(--accent-rgb),0.05);
  transform:translateY(-3px);
}
.launch-btn .launch-title{
  font-family:'Playfair Display', Georgia, serif;
  font-size:28px;
  font-weight:600;
  color:var(--text);
  letter-spacing:0.4px;
  text-align:center;
}
.launch-btn .launch-sub{
  font-size:13.5px;
  color:var(--muted);
  line-height:1.5;
  max-width:170px;
}

/* ---------- secondary home-page actions (Zen), sitting quietly underneath
   the three main launch buttons rather than competing with them ---------- */
.secondary-actions{
  display:flex;
  justify-content:center;
  margin-top:22px;
}
.zen-btn{
  padding:10px 26px;
  font-size:12px;
  letter-spacing:3px;
  text-transform:uppercase;
  font-weight:600;
  color:var(--muted);
  background:transparent;
  border:1px solid var(--border);
  border-radius:30px;
  text-decoration:none;
  transition:color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.zen-btn:hover{
  color:var(--green);
  border-color:var(--green-soft);
  background:rgba(var(--accent-rgb),0.05);
}

/* ---------- page transitions ---------- */
/* Word Pull is a classic multi-page site (separate .html files, no SPA
   router), so every nav link is a real browser navigation: the old document
   is fully torn down and a new one loads from scratch. All the JS-driven
   fading/morphing below runs *within* one document at a time, so it can
   dress up the moment just before unload and the moment right after load,
   but it can't touch the actual unload/load boundary itself -- that's a
   real gap where nothing of the old page exists yet nothing of the new page
   has painted, which is what reads as the background words "disappearing
   and reappearing" on click.
   Opting into cross-document View Transitions (supported in Chrome/Edge 126+
   and Safari 18.2+ as of 2026; older/unsupported browsers just navigate
   instantly as before, no regression) asks the browser itself to bridge
   that gap: it snapshots the old page, snapshots the new page's first
   paint, and crossfades between them, so the ambient word field dissolves
   into its next arrangement instead of hard-cutting away and back. */
@view-transition {
  navigation: auto;
}
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.5s;
  animation-timing-function: ease;
}

/* the clicked element's own box grows to fill the screen. As it grows it
   thickens into a frosted blur, masking/obscuring whatever it passes over
   instead of cutting to a flat color. The rest of the page dissolves at
   the same time. */
.morph-box{
  position:fixed;
  z-index:9999;
  background:rgba(10,10,11,0.5);
  backdrop-filter:blur(0px) saturate(140%);
  -webkit-backdrop-filter:blur(0px) saturate(140%);
  border:1px solid var(--green-soft);
  box-shadow:0 0 70px rgba(var(--accent-rgb),0.18);
  pointer-events:none;
  transition:
    top 0.6s cubic-bezier(0.22,0.85,0.16,1),
    left 0.6s cubic-bezier(0.22,0.85,0.16,1),
    width 0.6s cubic-bezier(0.22,0.85,0.16,1),
    height 0.6s cubic-bezier(0.22,0.85,0.16,1),
    border-radius 0.5s ease,
    backdrop-filter 0.6s ease,
    background 0.6s ease;
}
.morph-box.grown{
  background:rgba(10,10,11,0.9);
  backdrop-filter:blur(28px) saturate(140%);
  -webkit-backdrop-filter:blur(28px) saturate(140%);
}
/* only the foreground content dissolves; the ambient background words and
   the Home/About nav stay put and untouched throughout any transition --
   EXCEPT the particles transition (Zen only), which deliberately fades nav
   and #bgWords too via its own inline styles, for the "everything
   dissolves" effect */
body.page-dematerializing .stage{
  transition:opacity 0.4s ease;
  opacity:0;
}
/* zen.html has no .stage -- its content IS the write-overlay, always active */
body.page-dematerializing .write-overlay.active{
  transition:opacity 0.4s ease;
  opacity:0;
}

/* ---------- Zen's particle-dissolve transition ---------- */
.particle-canvas{
  position:fixed;
  inset:0;
  z-index:9999;
  pointer-events:none;
}

/* ---------- time's up: whole-screen color flash ----------
   Quickwrite's "time's up" moment: the entire viewport tints faintly in
   the current accent color for three quick flashes, then settles back to
   normal. Purely decorative, no masking, no layout impact -- just a flat
   tinted layer whose opacity pulses. Reads var(--accent-rgb) directly so
   it always follows whatever's picked on the Colors page with no JS
   needed to compute a color. */
.screen-flash{
  position:fixed;
  inset:0;
  background:rgba(var(--accent-rgb), 0.22);
  z-index:10050; /* above nav (10001) and #bgWords (10000) -- a true whole-screen flash */
  pointer-events:none;
  opacity:0;
}
.screen-flash.running{
  animation-name:screenFlashPulse;
  animation-timing-function:ease-in-out;
  animation-fill-mode:forwards;
}
@keyframes screenFlashPulse{
  0%   { opacity:0; }
  25%  { opacity:1; }
  55%  { opacity:0; }
  100% { opacity:0; }
}

/* the destination page starts blurred/faded and eases into focus, rather
   than popping in the instant the overlay disappears */
.page-enter-overlay{
  position:fixed;
  inset:0;
  background:rgba(10,10,11,0.9);
  backdrop-filter:blur(28px) saturate(140%);
  -webkit-backdrop-filter:blur(28px) saturate(140%);
  z-index:9998;
  opacity:1;
  transition:opacity 0.65s cubic-bezier(0.22,0.85,0.16,1), backdrop-filter 0.65s ease, background 0.65s ease;
}
.page-enter-overlay.hide{
  opacity:0;
  background:rgba(10,10,11,0);
  backdrop-filter:blur(0px);
  -webkit-backdrop-filter:blur(0px);
  pointer-events:none;
}

/* only the foreground stage eases in on load -- the nav bar is fixed chrome
   and must never visibly shift position between pages */
body.pre-materialize .stage{
  opacity:0;
  filter:blur(9px);
  transform:scale(0.98) translateY(6px);
}
.stage{
  transition:opacity 0.65s cubic-bezier(0.22,0.85,0.16,1), filter 0.65s cubic-bezier(0.22,0.85,0.16,1), transform 0.65s cubic-bezier(0.22,0.85,0.16,1);
}

/* #bgWords is intentionally NEVER part of any transition animation --
   opacity, blur, fade-in, none of it. It should read as one constant layer
   that is simply always there, on every page, through every transition.
   Only the foreground (.stage) ever appears/disappears. */

/* hide all chrome (including the ambient background) while actually
   writing -- that screen should be nothing but the words being typed */
body.is-writing .site-nav,
body.is-writing .back-btn,
body.is-writing #bgWords{
  display:none;
}

/* ---------- back button (next to the page title) ---------- */
.back-btn{
  position:absolute;
  left:0;
  top:50%;
  transform:translateY(-50%);
  padding:7px 16px;
  font-size:11px;
  letter-spacing:1.5px;
  text-transform:uppercase;
  color:var(--muted);
  border:1px solid var(--border);
  border-radius:20px;
  text-decoration:none;
  white-space:nowrap;
  transition:color 0.15s ease, border-color 0.15s ease;
}
.back-btn:hover{
  color:var(--green);
  border-color:var(--green-soft);
}
@media (max-width:600px){
  .back-btn{
    position:static;
    display:inline-block;
    transform:none;
    margin-bottom:12px;
  }
}
