/* ==========================================================================
   picturepuzzles.org — custom styles beyond Tailwind.
   Tailwind (CDN) handles page layout/spacing; this file owns the puzzle board,
   pieces, drag/snap animations, share UI, brand bits, and the admin heatmap.
   ========================================================================== */

:root {
    --slate-50:#f8fafc; --slate-100:#f1f5f9; --slate-200:#e2e8f0; --slate-300:#cbd5e1;
    --slate-400:#94a3b8; --slate-500:#64748b; --slate-700:#334155; --slate-900:#0f172a;
    --indigo-300:#a5b4fc; --indigo-400:#818cf8; --indigo-500:#6366f1; --indigo-600:#4f46e5;
    --sky-400:#38bdf8; --sky-500:#0ea5e9;
    --green-400:#4ade80; --green-500:#22c55e;
    --rose-500:#f43f5e; --rose-600:#e11d48;
    --color-primary:#6d28d9; /* site purple — matches the share-card footer bar */
    --white:#fff;
    --radius-md:0.75rem; --radius-lg:1rem; --radius-full:9999px;
    --shadow-sm:0 1px 2px 0 rgba(15,23,42,.08);
    --shadow-lg:0 10px 25px -5px rgba(15,23,42,.25);
    --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* ---------- Brand ---------- */
.brand-text {
    text-decoration:none;
    background:linear-gradient(to right,var(--indigo-600),var(--sky-500),var(--indigo-600));
    -webkit-background-clip:text; background-clip:text; color:transparent;
}
.brand-rule {
    height:.25rem; width:5rem; margin-top:.35rem;
    border-radius:var(--radius-full);
    background:linear-gradient(to right,var(--indigo-500),var(--sky-400),var(--indigo-500));
}

/* ---------- Buttons (custom, brand-styled) ---------- */
.btn-primary, .btn-ghost, .btn-secondary, .btn-copy-link {
    display:inline-flex; align-items:center; justify-content:center; gap:.5rem;
    border:none; cursor:pointer; font-family:inherit; font-weight:600; font-size:1rem;
    border-radius:var(--radius-lg); padding:.75rem 1.5rem; box-shadow:var(--shadow-sm);
    transition:background-color .15s ease, transform .05s ease;
}
.btn-primary { color:var(--white); background:var(--indigo-500); }
.btn-primary:hover { background:var(--indigo-600); }
.btn-primary:active { transform:translateY(1px); }
.btn-primary:disabled { background:var(--indigo-300); cursor:not-allowed; }
.btn-ghost { background:var(--white); color:var(--slate-700); border:1px solid var(--slate-200); }
.btn-ghost:hover { background:var(--slate-50); }
/* Secondary = outlined, same treatment as the ghost button (no new colors). */
.btn-secondary { background:var(--white); color:var(--slate-700); border:1px solid var(--slate-200); }
.btn-secondary:hover { background:var(--slate-50); }
/* Desktop completion popup Share/copy button — site purple (== footer bar).
   Its own transition makes the green "Copied!" → purple revert smooth. */
.btn-copy-link {
    background-color:var(--color-primary);
    color:var(--white);
    transition:background-color 0.2s ease, transform 0.2s ease;
}
.btn-copy-link:hover { background-color:#5b21b6; }
.btn-compact { padding:.45rem .8rem; font-size:.85rem; border-radius:var(--radius-md); }
.btn-danger { background:var(--rose-500); color:var(--white); border:1px solid var(--rose-500); }
.btn-danger:hover { background:var(--rose-600); }
.is-active-filter { background:var(--indigo-500); color:var(--white); border-color:var(--indigo-500); }

.badge {
    display:inline-flex; align-items:center; padding:.15rem .6rem; border-radius:var(--radius-full);
    background:var(--slate-100); color:var(--slate-700); font-size:.7rem; font-weight:700;
    text-transform:uppercase; letter-spacing:.05em;
}

.is-hidden { display:none !important; }

/* ---------- Upload / crop ---------- */
.dropzone {
    position:relative; display:flex; flex-direction:column; align-items:center; justify-content:center;
    text-align:center; gap:.75rem; min-height:60vh; padding:2rem 1.5rem;
    border:2px dashed var(--slate-300); border-radius:var(--radius-lg);
    background:rgba(255,255,255,.8); box-shadow:var(--shadow-sm); cursor:pointer;
    transition:border-color .15s ease, background-color .15s ease;
}
.dropzone.is-dragover { border-color:var(--indigo-500); background:rgba(99,102,241,.06); }
.cropper-stage__media { max-height:60vh; width:100%; }
.cropper-stage__media img { display:block; max-width:100%; }

/* ---------- Segmented difficulty ---------- */
.segmented {
    display:flex; border:1px solid var(--slate-200); border-radius:var(--radius-lg);
    overflow:hidden; background:var(--white); box-shadow:var(--shadow-sm);
}
.segmented__btn {
    flex:1 1 0; display:flex; flex-direction:column; align-items:center; gap:.15rem;
    padding:.6rem .5rem; border:none; border-right:1px solid var(--slate-200);
    background:var(--white); color:var(--slate-700); font-family:inherit; font-weight:700;
    font-size:.95rem; cursor:pointer; transition:background-color .15s ease, color .15s ease;
}
.segmented__btn:last-child { border-right:none; }
.segmented__btn:hover { background:var(--slate-50); }
.segmented__btn.is-active { background:var(--indigo-500); color:var(--white); }
.segmented__sub { font-size:.7rem; font-weight:600; opacity:.7; }

/* ---------- Puzzle toolbar: progress + timer pair, action buttons ---------- */
.puzzle-toolbar { display:flex; align-items:center; justify-content:space-between; gap:1rem; margin-bottom:1rem; }
.toolbar-actions { display:flex; gap:.5rem; flex-shrink:0; }
.status { display:flex; align-items:center; gap:.5rem; flex:1 1 auto; min-width:0; }

.progress {
    position:relative; flex:1 1 auto; min-width:6rem; height:1.6rem;
    border-radius:var(--radius-full); background:var(--slate-200); box-shadow:var(--shadow-sm); overflow:hidden;
}
.progress__fill {
    position:absolute; top:0; bottom:0; left:0; width:0; border-radius:var(--radius-full);
    background:linear-gradient(to right,var(--indigo-500),var(--sky-400)); transition:width .3s ease;
}
.progress__count {
    position:absolute; inset:0; z-index:1; display:flex; align-items:center; justify-content:center;
    font-size:.8rem; font-weight:700; color:var(--slate-700);
}
.progress.is-complete { animation:progress-complete-pulse .6s ease-out; }
@keyframes progress-complete-pulse {
    0%{ box-shadow:var(--shadow-sm); }
    30%{ box-shadow:0 0 0 4px rgba(34,197,94,.45); filter:brightness(1.12); }
    100%{ box-shadow:var(--shadow-sm); }
}
.timer {
    flex-shrink:0; display:inline-flex; align-items:center; height:1.6rem; padding:0 .75rem;
    border-radius:var(--radius-full); background:rgba(255,255,255,.85); border:1px solid var(--slate-200);
    box-shadow:var(--shadow-sm); font-size:.85rem; font-weight:700; font-variant-numeric:tabular-nums;
    color:var(--indigo-600);
}

/* ---------- Board + pieces ---------- */
.board {
    position:relative; margin:0 auto; background:rgba(255,255,255,.6);
    /* .board IS the unified container (picture area + .board__tray live inside).
       No border on the container itself — that doubled up with the gridline
       edges. The purple frame comes from .board__grid (picture: top/left/right
       + internal) and .board__tray (its sides + bottom), forming one continuous
       2px system. border-radius + overflow:hidden rounds all four outer corners
       and clips the frame lines to them. */
    border:none; border-radius:var(--radius-md); box-shadow:var(--shadow-sm);
    /* No touch-action here — only the draggable .piece sets touch-action:none.
       On the board container it swallowed the page's vertical-scroll gesture
       over the board, so iOS Safari never revealed its address bar. */
    overflow:hidden;
}
.board__grid {
    position:absolute; inset:0; box-sizing:border-box; pointer-events:none; opacity:1;
    /* Real 2px purple border on ALL FOUR sides of the picture area. The board's
       border-radius + overflow:hidden clips this border into clean rounded
       purple top corners (same 2px width as the sides). box-sizing:border-box
       keeps the border inside the JS-set width/height. background-origin:border-box
       aligns the internal gridlines to the piece grid while their would-be
       top/left edge lines fall under the border — so there's no doubling. */
    border:2px solid rgba(109,40,217,0.6);
    background-origin:border-box;
    background-image:
        linear-gradient(to right, rgba(109,40,217,0.6) 2px, transparent 2px),
        linear-gradient(to bottom, rgba(109,40,217,0.6) 2px, transparent 2px);
}
.board__tray {
    position:absolute; left:0; right:0; box-sizing:border-box; pointer-events:none;
    background:var(--slate-100);
    /* Tray is light gray, not purple. No top border — the grid's purple bottom
       border is the divider directly above it. Sides + bottom are light gray;
       the board's border-radius rounds the (gray) bottom corners. */
    border-left:2px solid var(--slate-300);
    border-right:2px solid var(--slate-300);
    border-bottom:2px solid var(--slate-300);
}
.board--error { width:100%; min-height:8rem; display:flex; align-items:center; justify-content:center; }
.board-error { padding:1.5rem; text-align:center; color:var(--slate-500); font-size:.9rem; line-height:1.5; }
.board-error a { color:var(--indigo-600); font-weight:600; }
.board__tray-label {
    position:absolute; top:4px; left:8px; font-size:.65rem; font-weight:600;
    letter-spacing:.08em; text-transform:uppercase; color:var(--slate-400);
}
.piece {
    position:absolute; top:0; left:0; background-repeat:no-repeat; border-radius:4px;
    box-shadow:0 1px 3px rgba(15,23,42,.35); cursor:grab; touch-action:none; will-change:transform;
}
.piece.is-dragging { cursor:grabbing; z-index:50; box-shadow:var(--shadow-lg); }
.piece.is-locked { cursor:default; box-shadow:none; border-radius:0; z-index:1; }

.piece.just-placed { animation:piece-flash .55s ease-out, piece-pop .45s ease-out; }
@keyframes piece-pop { 0%{scale:1;} 35%{scale:1.18;} 100%{scale:1;} }
@keyframes piece-flash { 0%{filter:brightness(1.7) saturate(1.25);} 100%{filter:none;} }
.piece.just-placed::after {
    content:""; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
    box-shadow:0 0 0 3px var(--green-500), 0 0 18px 7px var(--green-400);
    animation:piece-burst .55s ease-out forwards;
}
@keyframes piece-burst {
    0%{opacity:0; transform:scale(.92);} 25%{opacity:1; transform:scale(1.12);} 100%{opacity:0; transform:scale(1.18);}
}
.piece.piece-snapped::before {
    content:""; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
    animation:piece-snap-pulse .25s ease-out forwards;
}
@keyframes piece-snap-pulse {
    0%{ opacity:0; transform:scale(1); box-shadow:inset 0 0 0 2px rgba(255,255,255,0); }
    40%{ opacity:1; transform:scale(1.08); box-shadow:inset 0 0 0 3px var(--white), 0 0 12px 3px var(--indigo-300); }
    100%{ opacity:0; transform:scale(1); box-shadow:inset 0 0 0 0 rgba(255,255,255,0); }
}

/* ---------- First-visit hint banner ---------- */
.puzzle-banner {
    position:absolute; top:0; left:0; right:0; z-index:60; pointer-events:none; margin:0;
    padding:.55rem .9rem; background:rgba(15,23,42,.82); color:var(--white); font-size:.8rem;
    font-weight:600; text-align:center; border-top-left-radius:var(--radius-lg);
    border-top-right-radius:var(--radius-lg); opacity:1; transition:opacity .4s ease;
}
.puzzle-banner.is-leaving { opacity:0; }

/* ---------- Reference preview overlay ---------- */
.preview-overlay {
    position:fixed; inset:0; display:flex; align-items:center; justify-content:center;
    padding:1.5rem; background:rgba(15,23,42,.55); z-index:90;
}
.preview-card {
    position:relative; background:var(--white); border-radius:var(--radius-lg); box-shadow:var(--shadow-lg);
    padding:.5rem; max-width:min(90vw,32rem); max-height:85vh;
}
.preview-card__img { display:block; max-width:100%; max-height:calc(85vh - 1rem); border-radius:var(--radius-md); }
.preview-close, .share-card .preview-close {
    position:absolute; top:-.75rem; right:-.75rem; width:2rem; height:2rem;
    display:flex; align-items:center; justify-content:center; border:none; cursor:pointer;
    border-radius:var(--radius-full); background:var(--indigo-500); color:var(--white);
    font-size:1.25rem; line-height:1; box-shadow:var(--shadow-sm); transition:background-color .15s ease;
}
.preview-close:hover { background:var(--indigo-600); }

/* ---------- Completion / share overlay ---------- */
.complete-overlay {
    position:fixed; inset:0; display:flex; align-items:center; justify-content:center;
    padding:1.5rem; background:rgba(15,23,42,.55); z-index:100;
}
.complete-card {
    background:var(--white); border-radius:var(--radius-lg); box-shadow:var(--shadow-lg);
    padding:2rem 1.75rem; text-align:center; max-width:22rem; width:100%;
}
.complete-card__title {
    margin:0 0 .5rem; font-size:1.5rem; font-weight:800;
    background:linear-gradient(to right,var(--indigo-600),var(--sky-500),var(--indigo-600));
    -webkit-background-clip:text; background-clip:text; color:transparent;
}
.complete-card__text { margin:0 0 1.25rem; color:var(--slate-500); }
.share-card { position:relative; max-width:min(92vw,26rem); }
.share-card__canvas {
    display:block; width:100%; height:auto; margin:0 0 1rem; border-radius:var(--radius-md);
    box-shadow:var(--shadow-sm); background:var(--white);
}

/* Completion popup image area — purple backdrop so any exposed gap (aspect
   mismatch) shows the footer purple, not white. --color-primary == #6d28d9,
   the exact share-card footer bar color. */
.completion-image-container {
    background-color:var(--color-primary);
    display:flex;
    align-items:center;
    justify-content:center;
    width:100%;
    margin:0 0 1rem;            /* takes over the canvas's previous bottom spacing */
    border-radius:var(--radius-md);
}
.completion-image-container img,
.completion-image-container canvas {
    display:block;
    max-width:100%;
    max-height:100%;
    object-fit:contain;
    margin:0;                   /* no inner gap that would reveal purple as a strip */
}
/* Completion share controls — built per device by buildShareUI(). The
   container stacks its children; spacing comes from the element margins below
   (plus a gap between the two stacked full-width buttons on mobile). */
.share-actions { display:flex; flex-direction:column; }
.share-actions .btn-full + .btn-full { margin-top:10px; }

.share-url-text {
    text-align:center;
    font-size:0.9rem;
    color:#555;
    margin:8px 0 16px;
    user-select:all;   /* single click selects the entire URL — intentional */
    cursor:text;
    word-break:break-all;
}

.share-btn-row {
    display:flex;
    gap:10px;
    width:100%;
    margin-bottom:10px;
}

.btn-full { width:100%; }
/* transition here makes the Copy Link revert (green → original) smooth. */
.btn-half { flex:1; transition:background-color 0.3s ease, transform 0.2s ease, color 0.3s ease; }

/* Facebook / WhatsApp share icons — centered row between the primary action
   and Play Again (both layouts). Brand colors are intentional, not the palette. */
.social-share-row {
    display:flex;
    justify-content:center;
    gap:16px;
    margin:12px 0;
}
.social-btn {
    width:48px;
    height:48px;
    border-radius:50%;
    border:none;
    cursor:pointer;
    display:flex;
    align-items:center;
    justify-content:center;
    transition:transform 0.15s ease, opacity 0.15s ease;
    flex-shrink:0;
}
.social-btn:hover { transform:scale(1.08); opacity:0.92; }
.social-btn:active { transform:scale(0.96); }
.social-btn--facebook { background-color:#1877f2; }
.social-btn--whatsapp { background-color:#25d366; }

/* Home page: random completed-puzzle thumbnails (additive). */
.featured-puzzles {
  display: flex;
  flex-direction: row;
  gap: 12px;
  justify-content: center;
  align-items: flex-start;
  margin: 28px auto 20px;
  padding: 0 20px;
  width: 100%;
  box-sizing: border-box;
  max-width: 380px;
}

.featured-card {
  flex: 1 1 0;
  min-width: 0;
  max-width: 100px;   /* keep cards at three-across size even with fewer than 3 */
  display: flex;
  flex-direction: column;
  align-items: center;
  text-decoration: none;
  border-radius: 8px;
  overflow: hidden;
  transition: transform 0.15s ease, opacity 0.15s ease;
}

.featured-card:hover {
  transform: scale(1.04);
  opacity: 0.9;
}

.featured-card img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  display: block;
  border-radius: 8px;
}

.featured-meta {
  font-size: 11px;
  color: #888;
  margin-top: 4px;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 100%;
}

/* "Copied!" feedback state toggled by copyLink(); #22c55e == --green-500. */
.btn-copied {
    background-color:#22c55e !important;
    color:#fff !important;
    transform:scale(1.04);
    transition:background-color 0.2s ease, transform 0.2s ease, color 0.2s ease;
}

/* Admin heatmap */
.heatmap-wrap {
  background: #fff;
  border-radius: 12px;
  border: 1px solid #e5e7eb;
  padding: 24px;
  margin-bottom: 32px;
  overflow: hidden;
}

.heatmap-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 20px;
  flex-wrap: wrap;
  gap: 8px;
}

.heatmap-title {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #111;
}

.heatmap-subtitle {
  font-size: 13px;
  color: #888;
}

/* Horizontal scroll on mobile */
.heatmap-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.heatmap-table {
  border-collapse: separate;
  border-spacing: 3px;
  min-width: 700px;
}

.heatmap-corner {
  font-size: 11px;
  font-weight: 600;
  color: #888;
  text-align: left;
  padding: 0 12px 8px 0;
  white-space: nowrap;
}

.heatmap-hour {
  font-size: 11px;
  font-weight: 400;
  color: #888;
  text-align: center;
  padding: 0 0 8px;
  min-width: 28px;
}

.heatmap-day {
  font-size: 12px;
  font-weight: 600;
  color: #333;
  padding: 0 12px 0 0;
  white-space: nowrap;
  vertical-align: middle;
}

.heatmap-cell {
  width: 28px;
  height: 28px;
  border-radius: 4px;
  text-align: center;
  vertical-align: middle;
  font-size: 11px;
  background: transparent;
}

.heatmap-cell span {
  display: block;
  line-height: 28px;
  font-weight: 500;
}

/* 404 page */
.err-wrap {
    max-width: 30rem;
    margin: 1rem auto 0;
    text-align: center;
}

/* Decorative mini puzzle: one purple-bordered container holding the board + tray. */
.err-puzzle {
    width: 220px;
    margin: 0 auto 1.75rem;
    border: 2px solid var(--color-primary);
    border-radius: var(--radius-md);
    overflow: hidden;             /* clips the board/tray corners to the rounding */
    background: var(--white);
    box-shadow: var(--shadow-sm);
}

.err-board {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 2px;
    background: var(--color-primary);   /* shows through the gaps = purple gridlines */
}

.err-cell {
    aspect-ratio: 1 / 1;
    background: var(--white);
}

.err-cell--alt { background: rgba(109, 40, 217, 0.14); }  /* same purple, tinted */

.err-tray {
    display: flex;
    gap: 6px;
    align-items: center;
    justify-content: center;
    height: 46px;
    background: var(--white);
    border-top: 2px solid var(--color-primary);   /* divider between board and tray */
}

.err-piece {
    width: 22px;
    height: 22px;
    border-radius: 3px;
    background: rgba(109, 40, 217, 0.14);
    box-shadow: inset 0 0 0 1px rgba(109, 40, 217, 0.35);
}

.err-404 {
    font-size: 4rem;
    font-weight: 800;
    line-height: 1;
    color: var(--color-primary);
    margin-bottom: 0.5rem;
}

.err-title {
    margin: 0 0 0.5rem;
    font-size: 1.5rem;
    font-weight: 800;
    color: var(--slate-900);
}

.err-text {
    margin: 0 auto 1.5rem;
    max-width: 24rem;
    color: var(--slate-500);
    line-height: 1.5;
}

.err-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    justify-content: center;
}

/* Buttons reuse the site button base; recolored to brand purple for this page. */
.err-actions .btn-primary { background: var(--color-primary); }
.err-actions .btn-primary:hover { background: var(--color-primary); filter: brightness(0.92); }
.err-actions .btn-ghost { color: var(--color-primary); border-color: var(--color-primary); }
.err-actions .btn-ghost:hover { background: rgba(109, 40, 217, 0.06); }

/* Delete controls on puzzle cards */
.puzzle-card {
  position: relative; /* required: anchors the absolute .delete-btn to the card */
  overflow: hidden;   /* keeps the trash button clipped inside the card boundary */
}

.delete-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: none;
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 16px;
  z-index: 2;
  transition: background 0.15s ease, transform 0.15s ease;
  margin: 0;      /* defensive: nothing pushes it out of the corner */
  float: none;
}

.delete-btn:hover {
  background: #dc2626;
  transform: scale(1.08);
}

.delete-confirm {
  position: absolute;
  top: 8px;
  right: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  padding: 6px 10px;
  border-radius: 20px;
  font-size: 12px;
  z-index: 3;
  white-space: nowrap;
}

.delete-confirm span {
  font-size: 12px;
  color: #fff;
}

.confirm-yes {
  background: #dc2626;
  color: #fff;
  border: none;
  border-radius: 12px;
  padding: 3px 10px;
  font-size: 12px;
  cursor: pointer;
  transition: opacity 0.15s ease;
}

.confirm-yes:hover { opacity: 0.85; }

.confirm-no {
  background: transparent;
  color: #fff;
  border: 1px solid rgba(255,255,255,0.5);
  border-radius: 12px;
  padding: 3px 10px;
  font-size: 12px;
  cursor: pointer;
  transition: opacity 0.15s ease;
}

.confirm-no:hover { opacity: 0.75; }

/* Empty state injected by JS when the last card is deleted (spans the grid). */
.empty-state {
  grid-column: 1 / -1;
  text-align: center;
  color: var(--slate-500);
  padding: 2rem 0;
}
.empty-state a { color: var(--indigo-600); font-weight: 600; }

/* Record celebration (record-breaking completions) */
.shockwave-ring {
  position: fixed;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 4px solid #FFD700;
  transform: translate(-50%, -50%) scale(1);
  opacity: 1;
  pointer-events: none;
  z-index: 9999;
  animation: shockwave-expand 0.7s cubic-bezier(0.2, 0.8, 0.4, 1) forwards;
}

@keyframes shockwave-expand {
  0%   { transform: translate(-50%, -50%) scale(1);  opacity: 1; }
  60%  { opacity: 0.6; }
  100% { transform: translate(-50%, -50%) scale(18); opacity: 0; }
}

/* Board flash on record */
.board-flash { animation: board-flash-pulse 0.5s ease forwards; }

@keyframes board-flash-pulse {
  0%   { filter: brightness(1); }
  25%  { filter: brightness(1.6); }
  60%  { filter: brightness(1.2); }
  100% { filter: brightness(1); }
}

/* Piece nudge ripple — animates the `scale` PROPERTY (not transform:scale) so it
   composes with each piece's inline transform:translate() position. */
.piece-record-nudge { animation: piece-nudge 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards; }

@keyframes piece-nudge {
  0%   { scale: 1; }
  40%  { scale: 1.07; }
  100% { scale: 1; }
}

/* "New Record!" badge in the completion popup */
.record-badge {
  display: inline-block;
  background: #FFD700;
  color: #7c3aed;
  font-weight: 700;
  font-size: 14px;
  padding: 4px 16px;
  border-radius: 999px;
  margin-bottom: 8px;
  letter-spacing: 0.02em;
}

/* Admin moderation */
.mod-tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 24px;
  border-bottom: 2px solid #e5e7eb;
}
.mod-tab {
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 500;
  color: #888;
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: color 0.15s ease;
}
.mod-tab:hover { color: #333; }
.mod-tab--active { color: #6d28d9; border-bottom-color: #6d28d9; }
.mod-tab-count {
  background: #f0f0f0;
  color: #555;
  font-size: 11px;
  padding: 1px 7px;
  border-radius: 999px;
  font-weight: 600;
}
.mod-tab--active .mod-tab-count { background: #ede9fe; color: #6d28d9; }
.mod-tab-count--flagged { background: #fef2f2; color: #dc2626; }

.mod-sort-note { font-size: 12px; color: #aaa; margin: -8px 0 16px; }

/* Cards build on .puzzle-card (relative + overflow:hidden) + .puzzles-grid layout. */
.mod-card {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.mod-img-link {
  display: block;
  aspect-ratio: 1 / 1;
  overflow: hidden;
}
.mod-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.2s ease;
}
.mod-img:hover { transform: scale(1.03); }

.mod-delete-btn { z-index: 3; }

.mod-meta {
  padding: 6px 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  font-size: 11px;
  color: #888;
  border-bottom: 1px solid #f0f0f0;
}
.mod-meta span + span::before { content: '·'; margin-right: 4px; color: #ddd; }

.mod-badge--blocked {
  font-size: 10px;
  font-weight: 600;
  padding: 1px 6px;
  border-radius: 999px;
  background: #fef2f2;
  color: #dc2626;
}
.mod-badge--blocked::before { content: '' !important; margin: 0 !important; }

/* Three status buttons across the card bottom (each wrapped in its own form). */
.mod-status-btns { display: flex; border-top: 1px solid #f0f0f0; }
.mod-status-btns form { flex: 1; display: flex; }
.mod-status-btn {
  width: 100%;
  padding: 7px 4px;
  font-size: 11px;
  font-weight: 600;
  border: none;
  border-right: 1px solid #f0f0f0;
  background: #fafafa;
  color: #888;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
  white-space: nowrap;
}
.mod-status-btns form:last-child .mod-status-btn { border-right: none; }
.mod-status-btn:hover:not(:disabled) { background: #f0f0f0; color: #333; }
.mod-status-btn:disabled { cursor: default; }
.mod-status-btn--pending.mod-status-btn--active { background: #fef9c3; color: #854d0e; }
.mod-status-btn--approved.mod-status-btn--active { background: #f0fdf4; color: #16a34a; }
.mod-status-btn--flagged.mod-status-btn--active { background: #fef2f2; color: #dc2626; }

.mod-empty { text-align: center; padding: 64px 24px; color: #aaa; font-size: 14px; }

.mod-pagination { display: flex; gap: 6px; justify-content: center; margin-top: 24px; flex-wrap: wrap; }
.mod-page-btn {
  min-width: 36px;
  height: 36px;
  padding: 0 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  border: 1px solid #e5e7eb;
  font-size: 13px;
  text-decoration: none;
  color: #333;
  transition: background 0.15s ease;
}
.mod-page-btn:hover { background: #f5f5f5; }
.mod-page-btn--active { background: #6d28d9; color: #fff; border-color: #6d28d9; }

/* Daily puzzle CTA */
.daily-puzzle-wrap {
  display: flex;
  justify-content: center;
  margin-bottom: 28px;
}

.cta-daily-pill {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  padding: 0.75rem 1.75rem;
  font-size: 0.875rem;
  font-weight: 600;
  box-shadow: 0 10px 25px rgba(15, 23, 42, 0.25);
  overflow: hidden;
  text-decoration: none;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.cta-daily-pill:hover {
  transform: scale(1.03);
  box-shadow: 0 14px 30px rgba(15, 23, 42, 0.32);
}

.cta-daily-pill:active {
  transform: scale(0.98);
}

.cta-daily-pill-bg {
  position: absolute;
  inset: 0;
  background-image: linear-gradient(90deg, #fbbf24, #fb7185, #6366f1, #22c55e, #fbbf24);
  background-size: 300% 300%;
  animation: cta-pulse-gradient 6s ease-in-out infinite;
}

.cta-daily-pill-inner {
  position: relative;
  z-index: 1;
  color: #0f172a;
}

@keyframes cta-pulse-gradient {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

/* Daily puzzle empty state */
.daily-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 60vh;
  padding: 2rem;
}

.daily-empty-inner {
  text-align: center;
  max-width: 400px;
}

.daily-empty-icon {
  font-size: 48px;
  margin-bottom: 1rem;
}

.daily-empty-inner h1 {
  font-size: 24px;
  font-weight: 600;
  color: var(--color-text-primary, #111);
  margin-bottom: 0.5rem;
}

.daily-empty-inner p {
  font-size: 15px;
  color: #888;
  margin-bottom: 1.5rem;
  line-height: 1.6;
}

/* Sortable table headers */
.sortable-th {
  white-space: nowrap;
  user-select: none;
}

.sort-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: inherit;
  text-decoration: none;
  font-weight: 600;
  font-size: inherit;
  transition: color 0.15s ease;
}

.sort-link:hover {
  color: #6d28d9;
}

.sortable-th.sort-active .sort-link {
  color: #6d28d9;
}

.sort-arrow {
  font-size: 11px;
  line-height: 1;
}

.sort-arrow--inactive {
  opacity: 0.3;
}

.sort-arrow--asc,
.sort-arrow--desc {
  color: #6d28d9;
  opacity: 1;
}
