/* /wallpaper/ - the wallpaper pack page (wallpaper/wallpaper.js).

   COLOR COMES FROM THE SHELL, not from here. Every color below is a --wt-*
   token out of assets/cdo-watchtower.css, so light mode and Batman mode
   inherit ratios the shell already measured (--wt-ink 11.8:1 on paper and
   13.6:1 on the dark page, --wt-ink-soft 7.4 / 9.3, --wt-ink-quiet 5.0 / 5.2).
   Dark mode on this site is html[data-mode="batman"]; prefers-color-scheme is
   NOT a signal here and is deliberately absent from this file. The var()
   fallbacks are the same hex the shell defines, so a page that somehow loads
   without the shell stylesheet is still legible rather than black on black.

   WHICH BACKGROUND A RATIO IS AGAINST. This page's content sits inside
   .wt-shell, so in light mode the surface behind it is the shell's
   --wt-page-bg #f7f4ee, NOT the #efe9de that body.watchtower-body paints
   around it. In Batman mode the shell goes transparent and the body's #12150f
   is what shows through. Both columns below are measured against the color a
   reader actually sees behind that text.

   Measured 2026-08-05, recomputed from the tokens in cdo-watchtower.css
   (sRGB, WCAG 2.x, rgba composited, light then Batman):
     body text on a card    #26302b on #fffdf9 13.42   #ece7dc on #1e2522 12.68
     body text on the page  #26302b on #f7f4ee 12.42   #ece7dc on #12150f 14.94
     paragraph on the page  #475048 on #f7f4ee  7.62   #c2cabb on #12150f 10.93
     quiet text on a card   #5f6a60 on #fffdf9  5.56   #93a093 on #1e2522  5.73
     quiet text on the page #5f6a60 on #f7f4ee  5.15   #93a093 on #12150f  6.75
     size row name          #26302b on #f7f4ee 12.42   #ece7dc on #161a18 14.25
     size row note          #5f6a60 on #f7f4ee  5.15   #93a093 on #161a18  6.44
     primary button         #fffdf9 on #2c5f4e  7.24   #10140f on #8fd0b4 10.50
     link + focus ring      #2c5f4e on #fffdf9  7.24   #8fd0b4 on #1e2522  8.82
     tag text               #34403a on #ede7da  8.78   #b9e7d1 on chip     9.25
     promise on its panel   #26302b on #eef3ec 12.12   #ece7dc on panel   13.19
     field border (UI 3:1)  #767d73 on #fffdf9  4.17   #77837a on #1e2522  3.96
     focus ring   (UI 3:1)  #2c5f4e on #fffdf9  7.24   #8fd0b4 on #1e2522  8.82
   The lowest text pair on the page is 5.15:1 and the lowest UI pair is 3.86:1
   (the icon button's border on the page), so every one clears AA in BOTH modes.

   ONE PAIR IS DELIBERATELY BELOW 3:1: --wt-rule around .kcw-size, at 1.33 light
   and 1.22 Batman. That is the shell's documented position for a hairline
   BETWEEN blocks (see the note beside --wt-field-border in cdo-watchtower.css,
   which measures the same 1.33). The row is not an interactive control; the
   Save button inside it is, and it carries its own 7.24 / 10.50.
   The wallpaper image itself carries its own contract: lib/bundle.js picks the
   ink by measured contrast and substitutes the brand green rather than ship a
   background no ink can carry, and the page prints that number beside it.

   Mobile first. The two-column split only appears at 880px, because on a phone
   the whole job is: see the wallpaper, press one button. */

/* The shell stylesheet sets no font on <body>, and the tokens live on
   .wt-shell, so the page frame gets the family explicitly or the header and
   footer fall through to the browser default serif. */
body.watchtower-body {
  font-family: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

.kcw {
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 20px 72px;
  font: 400 16px/1.65 var(--wt-font-body, "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
  color: var(--wt-ink, #26302b);
}

/* ---------------------------------------------------------------- chrome -- */

.kcw-top {
  max-width: 1080px;
  margin: 0 auto;
  padding: 14px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.kcw-brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  text-decoration: none;
  color: var(--wt-ink, #26302b);
  font: 800 14px/1 var(--wt-font-display, "Montserrat", sans-serif);
  letter-spacing: 0.14em;
}
.kcw-brand svg { width: 26px; height: auto; }
.kcw-iconbtn {
  background: var(--wt-toggle-bg, transparent);
  border: 1.5px solid var(--wt-field-border, #767d73);
  color: var(--wt-ink, #26302b);
  border-radius: 999px;
  width: 42px;
  height: 42px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.kcw-iconbtn:hover { border-color: var(--wt-accent, #2c5f4e); }
html[data-mode="batman"] .kcw-iconbtn .kcw-sun { display: block; }
html[data-mode="batman"] .kcw-iconbtn .kcw-moon { display: none; }
.kcw-iconbtn .kcw-sun { display: none; }
.kcw-iconbtn .kcw-moon { display: block; }

.kcw-skip { position: absolute; left: -9999px; }
.kcw-skip:focus {
  position: fixed; left: 12px; top: 12px; z-index: 30;
  background: var(--wt-surface, #fffdf9);
  color: var(--wt-ink, #26302b);
  padding: 10px 14px; border-radius: 10px;
  border: 2px solid var(--wt-accent, #2c5f4e);
}

/* One visible focus treatment for every interactive thing on the page. */
.kcw a:focus-visible,
.kcw button:focus-visible,
.kcw input:focus-visible,
.kcw-top a:focus-visible,
.kcw-top button:focus-visible,
.kcw-foot a:focus-visible {
  outline: 3px solid var(--wt-accent, #2c5f4e);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ------------------------------------------------------------------ hero -- */

.kcw__eyebrow {
  font: 700 12.5px/1.5 var(--wt-font-display, "Montserrat", sans-serif);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--wt-ink-quiet, #5f6a60);
  margin: 10px 0 6px;
}
.kcw__title {
  font: 800 clamp(30px, 5.2vw, 44px)/1.12 var(--wt-font-display, "Montserrat", sans-serif);
  color: var(--wt-ink, #26302b);
  margin: 0 0 12px;
  letter-spacing: -0.01em;
}
.kcw__lede {
  font: 400 17.5px/1.62 var(--wt-font-body, "Montserrat", sans-serif);
  color: var(--wt-ink-soft, #475048);
  max-width: 62ch;
  margin: 0 0 10px;
}
/* The promise, verbatim. Set as one block so it can never be split. */
.kcw__promise {
  font: 600 15.5px/1.6 var(--wt-font-body, "Montserrat", sans-serif);
  color: var(--wt-ink, #26302b);
  background: var(--wt-panel-bg, #eef3ec);
  border: 1px solid var(--wt-panel-border, #d6e0d2);
  border-radius: 14px;
  padding: 14px 18px;
  margin: 20px 0 0;
  max-width: 62ch;
}

/* Visually hidden, still in the accessibility tree: the section heading that
   names the pack region for a screen reader without repeating the h1 on
   screen. */
.kcw--sr {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}
.kcw--center { text-align: center; }
.kcw--mt { margin-top: 14px; }

.kcw h2 {
  font: 700 22px/1.3 var(--wt-font-display, "Montserrat", sans-serif);
  color: var(--wt-ink, #26302b);
  margin: 40px 0 8px;
}
.kcw h3 {
  font: 700 16px/1.35 var(--wt-font-display, "Montserrat", sans-serif);
  color: var(--wt-ink, #26302b);
  margin: 0 0 4px;
}
.kcw p { margin: 0 0 12px; color: var(--wt-ink-soft, #475048); max-width: 68ch; }
/* :not(.kcw-btn) is load-bearing. `.kcw a` outranks `.kcw-btn` on specificity,
   so without it every button that is a link painted its label green on green
   and the pills shipped empty. */
.kcw a:not(.kcw-btn) { color: var(--wt-link, #2c5f4e); font-weight: 600; }
.kcw a:not(.kcw-btn):hover { color: var(--wt-link-hover, #1f4638); }
.kcw__quiet { color: var(--wt-ink-quiet, #5f6a60); font-size: 14.5px; }

/* ------------------------------------------------------------- the panel -- */

.kcw-pack {
  background: var(--wt-surface, #fffdf9);
  border: 1px solid var(--wt-rule, #e4ddcf);
  border-radius: 18px;
  padding: 20px;
  margin: 22px 0 0;
}
@media (min-width: 880px) { .kcw-pack { padding: 26px 28px; } }

.kcw-pack__h {
  font: 700 22px/1.3 var(--wt-font-display, "Montserrat", sans-serif);
  color: var(--wt-ink, #26302b);
  margin: 0 0 8px;
}
.kcw-pack__grid { display: grid; gap: 26px; align-items: start; }
@media (min-width: 880px) {
  .kcw-pack__grid { grid-template-columns: minmax(0, 280px) minmax(0, 1fr); gap: 34px; }
  /* The phone rides along while the size list scrolls past it. */
  .kcw-pack__side { position: sticky; top: 20px; }
}

/* The phone. A bezel, the real render inside it, and a dashed line showing
   where the lock-screen clock lands (lib/bundle.js WALLPAPER_SAFE.phone.top =
   0.26 of the canvas), which is the whole reason the words sit low. */
.kcw-phone {
  position: relative;
  width: 100%;
  max-width: 260px;
  margin: 0 auto;
  aspect-ratio: 1179 / 2556;
  border-radius: 30px;
  border: 8px solid var(--wt-rule-strong, #283a31);
  background: var(--wt-panel-bg, #eef3ec);
  overflow: hidden;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.18);
}
.kcw-phone__img { width: 100%; height: 100%; object-fit: cover; display: block; }
.kcw-phone__clock {
  position: absolute;
  left: 0; right: 0; top: 26%;
  border-top: 2px dashed rgba(255, 255, 255, 0.72);
  pointer-events: none;
}
.kcw-phone__clock span {
  position: absolute;
  right: 6px;
  top: -22px;
  font: 700 9.5px/1.4 var(--wt-font-display, "Montserrat", sans-serif);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #ffffff;
  /* The plate, not the artwork, is what guarantees this label: black at 62%
     over the lightest thing a poster could possibly be (pure white) still
     reads 6.19:1, and over the brand green 16.22:1. */
  background: rgba(0, 0, 0, 0.62);
  padding: 2px 6px;
  border-radius: 7px;
}
.kcw-pack__line {
  font: 800 clamp(19px, 2.6vw, 24px)/1.25 var(--wt-font-display, "Montserrat", sans-serif);
  color: var(--wt-ink, #26302b);
  margin: 0 0 8px;
  overflow-wrap: anywhere;
}
.kcw-pack__meta { font-size: 14px; color: var(--wt-ink-quiet, #5f6a60); margin: 0 0 16px; }

.kcw-btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  background: var(--wt-btn-bg, #2c5f4e);
  color: var(--wt-btn-ink, #fffdf9);
  border: 2px solid transparent;
  border-radius: 999px;
  font: 700 16px/1 var(--wt-font-display, "Montserrat", sans-serif);
  padding: 14px 24px;
  cursor: pointer;
  text-decoration: none;
}
.kcw-btn:hover { background: var(--wt-btn-bg-hover, #1f4638); color: var(--wt-btn-ink, #fffdf9); }
.kcw-btn--ghost {
  background: transparent;
  color: var(--wt-link, #2c5f4e);
  border-color: var(--wt-field-border, #767d73);
}
.kcw-btn--ghost:hover {
  background: transparent;
  color: var(--wt-link-hover, #1f4638);
  border-color: var(--wt-accent, #2c5f4e);
}
.kcw-btn--sm { font-size: 14px; padding: 9px 16px; }

/* ------------------------------------------------------------ size lists -- */

.kcw-group { margin: 22px 0 0; }
.kcw-group__head { display: flex; align-items: baseline; gap: 10px; margin: 0 0 8px; }
/* A TAG IS A 7px RECTANGLE on this site. Pills are buttons and nothing else. */
.kcw-tag {
  display: inline-block;
  border-radius: 7px;
  padding: 4px 10px;
  font: 700 11.5px/1.35 var(--wt-font-display, "Montserrat", sans-serif);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  background: var(--wt-chip-bg, #ede7da);
  border: 1px solid var(--wt-chip-border, #ddd4c2);
  color: var(--wt-chip-ink, #34403a);
}
.kcw-sizes { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.kcw-size {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  border: 1px solid var(--wt-rule, #e4ddcf);
  border-radius: 12px;
  padding: 11px 14px;
  background: var(--wt-page-bg, #f7f4ee);
}
.kcw-size__name { font-weight: 700; color: var(--wt-ink, #26302b); }
.kcw-size__note { color: var(--wt-ink-quiet, #5f6a60); font-size: 14px; }
/* The pixel count and its button travel together, so a narrow row wraps them
   as one block against the right edge instead of stranding a lone button. */
.kcw-size__right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 0 0 auto;
}
.kcw-size__px {
  font: 600 13.5px/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--wt-ink-soft, #475048);
  white-space: nowrap;
}

/* --------------------------------------------------------------- states --- */

.kcw-note {
  border: 1px solid var(--wt-rule, #e4ddcf);
  border-left: 4px solid var(--wt-warm, #be6b45);
  border-radius: 12px;
  padding: 14px 16px;
  background: var(--wt-page-bg, #f7f4ee);
  margin: 0 0 14px;
}
.kcw-note h3 { margin-bottom: 6px; }
.kcw-note p:last-child { margin-bottom: 0; }
.kcw-note__lang {
  font: 700 20px/1.3 var(--wt-font-display, "Montserrat", sans-serif);
  color: var(--wt-ink, #26302b);
  margin: 0 0 6px;
}

.kcw-find { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; margin: 0 0 10px; }
.kcw-find__label { display: block; font-weight: 700; font-size: 14px; margin: 0 0 6px; color: var(--wt-ink, #26302b); }
.kcw-find__field { flex: 1 1 260px; min-width: 0; }
.kcw-find input {
  width: 100%;
  border: 1px solid var(--wt-field-border, #767d73);
  border-radius: 12px;
  background: var(--wt-surface, #fffdf9);
  color: var(--wt-ink, #26302b);
  font: 400 16px/1.4 var(--wt-font-body, "Montserrat", sans-serif);
  padding: 12px 14px;
}
.kcw-msg { font-weight: 600; color: var(--wt-ink, #26302b); margin: 0 0 10px; }
.kcw-msg:empty { margin: 0; }

/* ---------------------------------------------------------------- how-to -- */

.kcw-steps { display: grid; gap: 14px; margin: 14px 0 0; padding: 0; list-style: none; }
@media (min-width: 720px) { .kcw-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.kcw-steps li {
  background: var(--wt-surface, #fffdf9);
  border: 1px solid var(--wt-rule, #e4ddcf);
  border-radius: 14px;
  padding: 14px 16px;
}
.kcw-steps p { margin: 0; font-size: 15px; }

.kcw-daily { background: var(--wt-surface, #fffdf9); border: 1px solid var(--wt-rule, #e4ddcf); border-radius: 16px; padding: 16px 20px; margin: 14px 0 0; }
.kcw-daily ol { margin: 8px 0 12px; padding-left: 20px; color: var(--wt-ink-soft, #475048); }
.kcw-daily li { margin: 0 0 6px; }
.kcw code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13.5px;
  background: var(--wt-chip-bg, #ede7da);
  border: 1px solid var(--wt-chip-border, #ddd4c2);
  color: var(--wt-chip-ink, #34403a);
  padding: 2px 6px;
  border-radius: 7px;
  overflow-wrap: anywhere;
}

/* ------------------------------------------------------ the browser maker --
   Carried over from the page this replaced so the in-browser phrase studio
   (assets/js/kc-wallpaper.js, not this agent's file) keeps the class names it
   builds. Retokenized only: the markup contract is untouched. */

.wp { display: grid; grid-template-columns: 1fr; gap: 24px; margin: 16px 0 0; }
@media (min-width: 760px) { .wp { grid-template-columns: 300px 1fr; align-items: start; } }
.wp__preview {
  background: var(--wt-surface, #fffdf9);
  border: 1px solid var(--wt-rule, #e4ddcf);
  border-radius: 18px;
  padding: 16px;
  display: flex;
  justify-content: center;
}
.wp__canvas { width: 100%; max-width: 240px; height: auto; border-radius: 14px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18); }
.wp__controls { display: flex; flex-direction: column; gap: 16px; }
.wp__field > span { display: block; font-weight: 700; font-size: 14px; margin-bottom: 6px; color: var(--wt-ink, #26302b); }
.wp__phraserow {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  background: var(--wt-surface, #fffdf9);
  border: 1px solid var(--wt-field-border, #767d73);
  border-radius: 12px;
  padding: 10px 12px;
}
.wp__phraserow:focus-within { border-color: var(--wt-accent, #2c5f4e); box-shadow: 0 0 0 3px var(--wt-accent, #2c5f4e); }
.wp__kc { font-weight: 800; letter-spacing: 0.04em; color: var(--wt-ink-quiet, #5f6a60); font-size: 14px; }
.wp__input {
  flex: 1; min-width: 140px; border: 0; background: transparent;
  color: var(--wt-ink, #26302b);
  font: 700 16px/1.4 var(--wt-font-body, "Montserrat", sans-serif);
}
.wp__input:focus-visible { outline: none; }
.wp__swatches { display: flex; flex-wrap: wrap; gap: 10px; }
.wp__sw { width: 38px; height: 38px; border-radius: 50%; border: 2px solid var(--wt-rule, #e4ddcf); cursor: pointer; }
.wp__sw.is-on, .wp__sw:focus-visible { outline: 3px solid var(--wt-accent, #2c5f4e); outline-offset: 2px; }
.wp__ratios { display: flex; flex-wrap: wrap; gap: 8px; }
.wp__ratio {
  background: transparent;
  border: 1.5px solid var(--wt-field-border, #767d73);
  color: var(--wt-ink, #26302b);
  border-radius: 999px;
  padding: 8px 14px;
  font: 600 13px/1 var(--wt-font-display, "Montserrat", sans-serif);
  cursor: pointer;
}
.wp__ratio.is-on { background: var(--wt-btn-bg, #2c5f4e); color: var(--wt-btn-ink, #fffdf9); border-color: var(--wt-btn-bg, #2c5f4e); }
.wp__ratio:focus-visible { outline: 3px solid var(--wt-accent, #2c5f4e); outline-offset: 2px; }
.wp__check { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--wt-ink-soft, #475048); }
.wp__btn {
  background: var(--wt-btn-bg, #2c5f4e);
  color: var(--wt-btn-ink, #fffdf9);
  border: 0; border-radius: 999px;
  font: 800 16px/1 var(--wt-font-display, "Montserrat", sans-serif);
  padding: 14px 26px; cursor: pointer; align-self: flex-start;
}
.wp__btn:hover { background: var(--wt-btn-bg-hover, #1f4638); }
.wp__btn:focus-visible { outline: 3px solid var(--wt-accent, #2c5f4e); outline-offset: 2px; }
.wp__msg { font-weight: 600; color: var(--wt-ink, #26302b); min-height: 1.3em; margin: 0; }
.wp__hint { color: var(--wt-ink-quiet, #5f6a60); font-size: 13.5px; margin: 0; }

/* ---------------------------------------------------------------- footer -- */

.kcw-foot {
  border-top: 1px solid var(--wt-rule, #e4ddcf);
  margin-top: 44px;
  padding: 24px 20px 48px;
  color: var(--wt-ink-soft, #475048);
  font-size: 14px;
  text-align: center;
}
.kcw-foot p { margin: 0 0 8px; }
.kcw-foot a { color: var(--wt-link, #2c5f4e); font-weight: 600; }

@media (prefers-reduced-motion: reduce) {
  .kcw *, .kcw-top * { transition: none !important; animation: none !important; }
}
