/*!* Registering this as a <length-percentage> lets the browser smoothly*/
/*   interpolate it (and, transitively, the gradient built from it below)*/
/*   instead of snapping to the new value the instant the card's height*/
/*   changes (e.g. a new history row appearing after a guess/hint). *!*/
/*@property --bg-fade-start {*/
/*  syntax: "<length-percentage>";*/
/*  inherits: true;*/
/*  initial-value: 50%;*/
/*}*/

/* These files are served by Exaqtly, so visitors do not need either font
   installed locally and the design does not rely on Google Fonts access. */
@font-face {
  font-family: "Ubuntu Mono Bold";
  src: url("fonts/Ubuntu-Mono-Bold.ttf") format("truetype");
  font-style: normal;
  font-weight: 700;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Sans Light";
  src: url("fonts/IBMPlexSans-Light.ttf") format("truetype");
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Sans Regular";
  src: url("fonts/IBMPlexSans-Regular.ttf") format("truetype");
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Sans Medium";
  src: url("fonts/IBMPlexSans-Medium.ttf") format("truetype");
  font-style: normal;
  font-weight: 500;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Sans Medium";
  src: url("fonts/IBMPlexSans-Medium.ttf") format("truetype");
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Sans Bold";
  src: url("fonts/IBMPlexSans-Bold.ttf") format("truetype");
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #f6f5f1;
  --card-bg: #dddddd;
  --ink: #363333;
  --muted: #787c7e;
  --border: #d3d6da;

  /* --accent / --logo-accent are set per-season below (see the
     html.season-* rules) based on today's date, computed server-side in
     app.py's current_season(). These are just a fallback in case that
     class is ever missing. */
  --accent: #5d6442;
  --logo-accent: #b6c18b;

  --correct: #538d4e;
  --wrong: #b0413e;
  --dot-empty: #e3e3e3;

  /* Background image fade: the % of the image's height (from its top) at
     which it becomes fully opaque. Lower = shorter/sharper fade, higher =
     longer/softer. See .bg-fade for the full explanation. */
  --bg-fade-solid-at: 75%;
}

html.season-winter {
  --accent: #424d64;
  --logo-accent: #96a9d1;
}

html.season-spring {
  --accent: #426459;
  --logo-accent: #7db6a3;
}

html.season-summer {
  --accent: #5d6442;
  --logo-accent: #b6c18b;
}

html.season-autumn {
  --accent: #645142;
  --logo-accent: #bc9b81;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  min-height: 100vh;
  color: var(--ink);
  font-family: "IBM Plex Sans Regular", Helvetica, Arial, sans-serif;
}

body {
  position: relative;
  background-color: var(--bg);
}

.bg-fade {
  /* Swap static/background.png for a different image any time - same
     filename, no other changes needed. The flat accent-color layer is
     blended over the photo (blend mode "color") to tint it, keeping the
     photo's original luminance/detail but recoloring it to match --accent.

     This box is sized to the image's OWN aspect ratio and pinned to the
     bottom of the page, so it is exactly as tall as the fully-visible
     image on any screen. The fade below is then a simple percentage of
     this box - it always begins at the image's own top edge and ramps
     down over it, so there is never a hard seam regardless of screen
     shape. --bg-image-aspect (width/height) is set from the real image by
     main.js; the literal here is a fallback for the current image. */
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: auto;
  aspect-ratio: var(--bg-image-aspect, 1983 / 793);
  pointer-events: none;
  background-image: linear-gradient(var(--accent), var(--accent)), url("background.png");
  background-size: 100% 100%, 100% 100%;
  background-repeat: no-repeat, no-repeat;
  background-blend-mode: color;
  /* THE ONE KNOB: where the image reaches full opacity, as a % of its own
     height from the top. Smaller % = image appears sooner (sharper edge).
     Larger % = longer, softer fade. 100% would fade across the whole
     image. Tune --bg-fade-solid-at to taste. */
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    black var(--bg-fade-solid-at, 75%)
  );
  mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    black var(--bg-fade-solid-at, 75%)
  );
}

.page {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 32px 16px 48px;
}

body.keyboard-open .page {
  padding: 12px 16px 12px;
}

body.keyboard-open .header,
body.keyboard-open .menu-btn {
  display: none;
}

body.keyboard-open .card {
  padding: 16px 18px;
}

body.keyboard-open .quote-wrap {
  margin: 20px 0 16px;
}

body.keyboard-open .author {
  margin: 0 0 12px;
}

body.keyboard-open .round-rows {
  gap: 6px;
}

body.keyboard-open .secondary-actions {
  margin-top: 10px;
}

.top-bar {
  position: relative;
  width: 100%;
  display: flex;
  justify-content: center;
}

.menu-btn {
  position: absolute;
  top: 0;
  left: 16px;
  z-index: 30;
  width: 40px;
  height: 40px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  background: rgba(255, 255, 255, 0.88);
  border: 1px solid var(--border);
  border-radius: 10px;
  backdrop-filter: blur(6px);
  cursor: pointer;
}

.menu-btn span {
  display: block;
  width: 18px;
  height: 2px;
  background: var(--accent);
  border-radius: 2px;
}

.menu-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.25);
  z-index: 20;
}

.menu-overlay.visible {
  display: block;
}

.menu-panel {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 25;
  width: 260px;
  max-width: 80vw;
  background: var(--card-bg);
  box-shadow: 2px 0 16px rgba(0, 0, 0, 0.15);
  padding: 72px 16px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  transform: translateX(-100%);
  transition: transform 0.2s ease;
}

.menu-panel.visible {
  transform: translateX(0);
}

.menu-auth {
  font-size: 1.1rem;
  color: var(--muted);
  padding: 8px 10px 16px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 8px;
}

.menu-item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  color: var(--ink);
  font-size: 1.1rem;
  font-weight: 600;
  cursor: pointer;
  padding: 10px;
  border-radius: 8px;
}

.menu-item:hover {
  background: var(--bg);
}

.auth-link {
  color: var(--accent);
  font-weight: 600;
  text-decoration: underline;
  cursor: pointer;
}

.auth-link:hover {
  opacity: 0.7;
}

.auth-email-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 8px;
  max-width: 260px;
}

.auth-email-input {
  min-width: 0;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.95rem;
  outline: none;
}

.auth-email-input:focus {
  border-color: var(--accent);
}

.auth-email-send {
  white-space: nowrap;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 6px;
  padding: 6px 12px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.auth-email-send:hover:not(:disabled) {
  opacity: 0.85;
}

.auth-email-send:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.auth-email-status {
  margin: 6px 0 0;
  font-size: 0.9rem;
  color: var(--muted);
}

.header {
  text-align: center;
  transform: translateY(-18px);
  margin-bottom: 24px;
  padding: 14px 28px;
  background: rgba(255, 255, 255, 0.0);
  border-radius: 18px;
  backdrop-filter: blur(6px);
}

.header h1 {
  display: flex;
  justify-content: center;
  font-size: 3.3rem;
  letter-spacing: 0.05em;
  margin: 0;
  border-bottom: 2px solid var(--border);
  padding-bottom: 8px;
  font-family: "Ubuntu Mono Bold";
}

.header h1 .logo-q {
  color: var(--ink) !important;
}

.header h1 .logo-accent-letter {
  color: var(--logo-accent) !important;
}

.logo-accent-letter {
  color: var(--logo-accent);
}

.subtitle {
  margin: 8px 0 0;
  color: var(--muted);
  font-family: "IBM Plex Sans Light", Helvetica, Arial, sans-serif;
  font-weight: 300;
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.card {
  position: relative;
  margin-top: -28px;
  background: color-mix(in srgb, var(--card-bg) 0%, transparent);
  backdrop-filter: blur(6px);
  border-radius: 16px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08);
  padding: 17px 30px 30px;
  width: 100%;
  max-width: 760px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.puzzle-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  max-width: 680px;
  min-height: 24px;
  margin-bottom: 12px;
}

.puzzle-label {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: 0.02em;
  transform: translateX(-18px);
}

.puzzle-bar-actions {
  display: flex;
  gap: 12px;
}

.link-btn {
  background: none;
  border: none;
  color: var(--accent);
  font-size: 0.95rem;
  font-weight: 600;
  text-decoration: underline;
  cursor: pointer;
  padding: 4px;
}

.link-btn:hover {
  opacity: 0.7;
}

.link-btn.hidden {
  display: none;
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1.5px solid var(--accent);
  text-decoration: none;
  padding: 0;
}

.quote-wrap {
  position: relative;
  width: 100%;
  max-width: 680px;
  margin: 28px 0 26px;
  display: flex;
  justify-content: center;
  min-height: 1.5em;
}

.quote-wrap::before,
.quote-wrap::after {
  font-family: Georgia, "Times New Roman", serif;
  font-style: normal;
  font-weight: 700;
  font-size: 5.1rem;
  line-height: 1;
  color: var(--accent);
  opacity: 0.12;
  pointer-events: none;
  user-select: none;
}

.quote-wrap::before {
  content: "\201C";
  position: absolute;
  top: -38px;
  left: -18px;
}

.quote-wrap::after {
  content: "\201D";
  position: absolute;
  bottom: -68px;
  right: -18px;
}

#quote-canvas {
  display: block;
  max-width: 100%;
}

.author {
  margin: 0 0 16px;
  color: var(--muted);
  font-weight: 600;
  font-size: 1.1rem;
}

.round-rows {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  max-width: 480px;
}

.round-row {
  display: flex;
  align-items: center;
  gap: 10px;
  opacity: 0.45;
  transition: opacity 0.2s ease;
}

.round-row-active {
  opacity: 1;
}

.round-number {
  flex: 0 0 auto;
  width: 20px;
  text-align: center;
  font-size: 1rem;
  font-weight: 700;
  color: var(--muted);
}

.round-row-active .round-number {
  color: var(--accent);
}

.round-row > .round-ghost-btn,
.round-row > .primary-btn,
.round-row > .guess-form,
.round-row > .round-result {
  flex: 1;
  /* Without this, a flex item can't shrink below its own content's
     intrinsic width (the default min-width: auto) - so "Get hint" being
     longer text than "Guess" pushed hint-btn wider than its equal share,
     squeezing the guess-form/button narrower instead of the two matching. */
  min-width: 0;
}

.round-row > .round-or {
  flex: 0 0 auto;
  font-size: 0.9rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.round-row > .round-or.hidden {
  display: none;
}

.round-ghost-btn {
  padding: 10px 22px;
  border: none;
  border-radius: 8px;
  background: var(--dot-empty);
  color: var(--muted);
  font-size: 1.1rem;
  font-weight: 600;
  cursor: not-allowed;
}

#guess-cancel-btn {
  flex: 0 0 auto;
  width: 48px;
  padding: 10px 0;
  text-align: center;
}

.round-result {
  padding: 10px 16px;
  border-radius: 8px;
  font-weight: 600;
  text-align: center;
}

.round-result-correct {
  background: rgba(83, 141, 78, 0.15);
  color: var(--correct);
}

.round-result-incorrect {
  background: rgba(176, 65, 62, 0.12);
  color: var(--wrong);
}

.round-result-hints {
  margin-left: 8px;
  font-size: 0.8em;
  font-weight: 500;
  opacity: 0.75;
}

@media (max-width: 640px) {
  body.guess-focused .top-bar,
  body.guess-focused .puzzle-bar,
  body.guess-focused .author,
  body.guess-focused .round-row:not(.round-row-active) {
    display: none;
  }
}

.guess-form {
  display: flex;
  gap: 8px;
}

/* With flex-basis:0/min-width:0, an item's *content* can shrink to zero
   but its padding can't - padding is an unavoidable floor added on top of
   the equal growth share. #hint-btn's default 44px of horizontal padding
   would make it permanently 44px wider than the (unpadded) .guess-form
   wrapper despite equal flex-grow. Zeroing the horizontal padding on BOTH
   the hint button and the guess button inside the form gives every flex
   item the same (zero) floor, so the two visible buttons come out exactly
   the same width - matching the ghost rows, whose two buttons carry equal
   padding and therefore already split evenly. Labels stay centered, so no
   padding is needed horizontally. */
#guess-toggle-btn,
#hint-btn {
  padding-left: 0;
  padding-right: 0;
}

.input-ghost-wrap {
  flex: 1;
  min-width: 0;
  position: relative;
}

/* Ghost suggestion shown in gray behind the input text. Inset by 2px to
   sit inside the input's border, then match the input's padding exactly. */
.input-ghost {
  position: absolute;
  inset: 2px;
  padding: 10px 16px;
  font-size: 1.1rem;
  font: inherit;
  font-size: 1.1rem;
  white-space: pre;
  overflow: hidden;
  pointer-events: none;
  display: flex;
  align-items: center;
}

.input-ghost .ghost-typed {
  color: transparent;
}

.input-ghost .ghost-hint {
  color: #aaa;
}

.guess-form input {
  width: 100%;
  min-width: 0;
  padding: 10px 16px;
  border: 2px solid var(--border);
  border-radius: 8px;
  font: inherit;
  font-size: 1.1rem;
  background: transparent;
  outline: none;
  transition: border-color 0.2s ease;
  position: relative;
}

.guess-form input.hidden {
  display: none;
}

.input-ghost-wrap:has(input.hidden) {
  display: none;
}

.guess-form input:focus {
  border-color: var(--accent);
}

.guess-form input:disabled,
.guess-form input:read-only {
  background: #f0f0f0;
  color: var(--muted);
}

.primary-btn {
  width: 100%;
  padding: 10px 22px;
  border: none;
  border-radius: 8px;
  background: var(--accent);
  color: #fff;
  font-size: 1.1rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s ease, transform 0.1s ease;
}

/* While the guess input is open, its button becomes a small checkmark
   instead of stretching to fill the form's whole slot. */
.input-ghost-wrap:not(:has(input.hidden)) ~ .primary-btn {
  width: 48px;
  flex: 0 0 auto;
  padding: 10px 0;
  text-align: center;
}

.primary-btn:hover:not(:disabled) {
  background: #363333;
}

.primary-btn:active:not(:disabled) {
  transform: scale(0.97);
}

.primary-btn:disabled {
  background: var(--dot-empty);
  cursor: not-allowed;
}

.primary-btn.hidden {
  display: none;
}

.secondary-actions {
  display: flex;
  gap: 10px;
  margin-top: 10px;
  flex-wrap: wrap;
  justify-content: center;
}

.next-btn {
  padding: 8px 16px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  font-size: 0.95rem;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}

.next-btn:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}

.next-btn:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

.next-btn.hidden {
  display: none;
}

/* Hide the legacy control on older cached page templates as well. */
#next-quote-btn {
  display: none !important;
}

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s ease;
  padding: 16px;
}

.modal-overlay.visible {
  opacity: 1;
  visibility: visible;
}

.modal {
  background: var(--card-bg);
  border-radius: 16px;
  padding: 36px 32px;
  max-width: 480px;
  width: 100%;
  text-align: center;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
  transform: translateY(12px);
  transition: transform 0.25s ease;
}

.modal-overlay.visible .modal {
  transform: translateY(0);
}

.modal h2 {
  margin: 0 0 32px;
  font-size: 1.9rem;
}

.modal-quote {
  margin: 0 0 12px;
  padding: 0;
  border: none;
  font-family: "Courier New", monospace;
  font-style: italic;
  font-size: 1.25rem;
  line-height: 1.6;
  color: var(--ink);
}

.modal-author {
  margin: 0 0 24px;
  color: var(--muted);
  font-weight: 600;
}

.modal-context {
  margin: -8px 0 24px;
  padding: 12px 14px;
  border-radius: 8px;
  background: var(--bg);
  color: var(--ink);
  font-size: 1rem;
  line-height: 1.5;
  text-align: left;
}

.modal-context.hidden {
  display: none;
}

.modal button:not(.archive-cell) {
  padding: 12px 24px;
  border: none;
  border-radius: 8px;
  background: var(--accent);
  color: #fff;
  font-size: 1.1rem;
  font-weight: 600;
  cursor: pointer;
}

.modal button:not(.archive-cell):hover {
  background: #000;
}

#play-again.hidden {
  display: none;
}

.giveup-text {
  margin: 0 0 20px;
  color: var(--muted);
  font-size: 1rem;
  line-height: 1.5;
}

.invalid-guess-modal {
  max-width: 360px;
}

.invalid-guess-text {
  margin: 0 0 20px;
  color: var(--ink);
  font-size: 1rem;
  line-height: 1.5;
}

.modal-actions {
  display: flex;
  gap: 10px;
}

.modal-actions button {
  flex: 1;
}

.modal-btn-secondary {
  padding: 12px 24px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: transparent;
  color: var(--ink);
  font-size: 1.1rem;
  font-weight: 600;
  cursor: pointer;
}

.modal-btn-secondary:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.modal-btn-danger {
  padding: 12px 24px;
  border: none;
  border-radius: 8px;
  background: var(--wrong);
  color: #fff;
  font-size: 1.1rem;
  font-weight: 600;
  cursor: pointer;
}

.modal-btn-danger:hover {
  background: #8a3230;
}

.archive-modal {
  max-width: 420px;
  text-align: left;
}

.archive-modal h2 {
  text-align: center;
}

.archive-hint {
  margin: 0 0 16px;
  color: var(--muted);
  font-size: 0.95rem;
  text-align: center;
}

.archive-month-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.archive-month-label {
  font-weight: 600;
  font-size: 1rem;
  text-align: center;
  flex: 1;
}

.archive-month-btn {
  width: 32px;
  height: 32px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease, opacity 0.2s ease;
}

.archive-month-btn:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}

.archive-month-btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

.archive-calendar {
  max-height: 400px;
  overflow-x: hidden;
  overflow-y: auto;
  margin-bottom: 20px;
}

.archive-weekdays {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 8px;
}

.archive-weekdays span {
  text-align: center;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.archive-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 8px;
}

.archive-cell-empty {
  visibility: hidden;
}

.archive-cell {
  -webkit-appearance: none;
  appearance: none;
  box-sizing: border-box;
  position: relative;
  min-width: 0;
  margin: 0;
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--border);
  border-radius: 10px;
  background: var(--bg);
  color: var(--ink);
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.2s ease, transform 0.1s ease, background-color 0.2s ease;
}

.archive-cell:hover:not(:disabled) {
  border-color: var(--accent);
  transform: scale(1.05);
}

.archive-cell:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.archive-cell-icon {
  position: absolute;
  top: 2px;
  right: 4px;
  font-size: 0.7rem;
  line-height: 1;
}

.archive-cell-won {
  background: rgba(83, 141, 78, 0.15);
  border-color: transparent;
  color: var(--correct);
}

.archive-cell-lost {
  background: rgba(176, 65, 62, 0.12);
  border-color: transparent;
  color: var(--wrong);
}

.archive-cell-playing {
  background: rgba(18, 18, 19, 0.08);
  border-color: var(--accent);
  color: var(--accent);
}

.archive-cell-not_started {
  background: var(--bg);
  color: var(--muted);
}

.archive-cell-today {
  border-color: var(--accent);
  border-width: 2px;
  font-weight: 700;
  color: var(--accent);
}

.archive-empty {
  color: var(--muted);
  font-size: 1rem;
  text-align: center;
  padding: 12px 0;
}

#archive-close {
  width: 100%;
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--border);
}

#archive-close:hover {
  background: var(--bg);
}

.howto-modal {
  max-width: 460px;
  text-align: left;
}

.howto-modal h2 {
  text-align: center;
}

.howto-list {
  margin: 0 0 22px;
  padding-left: 20px;
  color: var(--ink);
  font-size: 1.02rem;
  line-height: 1.6;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.howto-list li {
  padding-left: 2px;
}

.howto-correct {
  color: var(--correct);
  font-weight: 700;
}

#howto-close {
  width: 100%;
}


@media (max-width: 480px) {
  .card {
    padding: 26px 18px 20px;
  }
}
