/*
 * Self-contained sub-palette for the dashboard mockup component only.
 * Every hex value below is copied verbatim from the real DonkeyCMS admin's
 * dark theme (blog/includes/admin_theme.php) — this mockup is a static
 * reproduction of the real product, not an invented app design, so its
 * colors are calibrated against the source rather than picked to taste.
 * Declared on .dm-window (the component's root element) so every
 * descendant inherits them via normal CSS custom-property cascade.
 */
.dm-window {
  --dm-bg-outer: #1c2740;   /* real --admin-surface */
  --dm-bg-inset: #24304d;   /* real --admin-surface-alt */
  --dm-bg-deep: #131c30;    /* slightly darker than surface, for the address bar well */
  --dm-border: #2e3b59;     /* real --admin-border */
  --dm-dot: #3a4a6b;        /* real --admin-border-strong */
  --dm-text: #eef1f8;       /* real --admin-text */
  --dm-text-muted: #93a0bf; /* real --admin-text-muted */

  --dm-green: #7fd996;      --dm-green-soft: #1f3d24;
  --dm-amber: #e8c874;      --dm-amber-soft: #4a3d1f;
  --dm-purple: #c9a3f0;     --dm-purple-soft: #3a2c4a;
  --dm-blue: #8fb3f5;       --dm-blue-soft: #1f2c4a;
  --dm-teal: #6dd9d9;       --dm-teal-soft: #1a3a3a;
  --dm-rose: #f2a3c9;       --dm-rose-soft: #3a1f2e;
  --dm-indigo: #a3b3f0;     --dm-indigo-soft: #2a2c4a;
  --dm-fuchsia: #f0a3d9;    --dm-fuchsia-soft: #4a2c42;

  position: relative;
  z-index: 1;
  border: 2px solid transparent;
  border-radius: var(--radius-lg);
  /* Crisp two-color gradient stroke — the classic dual-background
     border-box trick: an opaque fill painted into the padding-box, and
     the gradient painted into the border-box behind it, so only the 2px
     border ring itself shows the gradient. This is a real, sharp stroke
     line (not the soft blurred halo below), fading directly from red to
     light blue across the window's diagonal. */
  background:
    linear-gradient(var(--dm-bg-outer), var(--dm-bg-outer)) padding-box,
    linear-gradient(135deg, var(--hero-red), var(--hero-blue)) border-box;
  overflow: hidden;
  box-shadow: 0 40px 100px rgba(0, 0, 0, 0.6);
}

/* Traveling-light-beam experiment (a CSS conic-gradient ring, then a
   Canvas 2D comet-trail + following glow, trying to approximate
   huly.io's "Sync with GitHub" mockup effect — that one turned out to
   be WebGL/canvas-rendered) removed 2026-08-12 at Buğra's request — it
   didn't read as close enough to the reference to be worth keeping.
   See git history for the full attempt if this gets revisited later.
   The crisp static gradient border on .dm-window above, and the static
   corner blooms below, are both unrelated earlier work and unaffected. */
.dm-window-wrap { position: relative; }

/* ===== Corner light blooms, take 5 — same two triangles, but the shape
   moved from a CSS clip-path'd <span> into a real <svg><polygon> with
   an SVG <feGaussianBlur> (markup in dashboard-mockup.php). CSS
   filter:blur() combined with clip-path on the same element is a real,
   documented gotcha: browsers commonly size the element's filter region
   to the *clipped* shape with no margin for the blur to spread into, so
   the blur gets clipped right back to the same hard edge it was meant
   to soften — explains why take 4 stayed visibly crisp no matter how
   high the blur value went (13px, then 20px, genuinely applied per
   getComputedStyle both times, just invisible). SVG's <filter> element
   takes an explicit x/y/width/height region (set generously oversized
   in the markup) specifically so this can't happen — the blur has real,
   guaranteed room to spread past the polygon's own edges.

   This rule now only handles position/size (the overflow-safety-tested
   part) — the shape, fill color, and blur all live in the SVG markup
   itself. */
.dm-bloom {
  position: absolute;
  display: block;
  overflow: visible;
  z-index: 0;
  pointer-events: none;
}
.dm-bloom-blue {
  top: -25px;
  left: -25px;
  width: 460px;
  height: 460px;
}
.dm-bloom-red {
  bottom: -25px;
  right: -25px;
  width: 460px;
  height: 460px;
}

/* Narrower viewports — the 140px/-75px values first tried here
   overflowed 36px past the edge at 768px (isolated the cause the same
   way as every prior round: hid one triangle at a time and found red
   was the actual culprit, blue was already safe at every size tried).
   Empirically swept from there; 80px/-25px is the largest size that
   stays genuinely clear with real margin, not just barely. */
@media (max-width: 1200px) {
  .dm-bloom-blue,
  .dm-bloom-red {
    width: 150px;
    height: 150px;
  }
  .dm-bloom-blue { top: -10px; left: -10px; }
  .dm-bloom-red { bottom: -10px; right: -10px; }
}

/* Phone widths (≤520px) are a different situation from the tablet range
   above: .dm-window is given a near-desktop width there (see the
   crop-and-bleed block further down) instead of shrinking, so the
   mockup itself is close to desktop scale again — the 150px blooms
   tuned for the *shrunk* tablet-era window read as too small and
   insignificant next to it. Sized up toward desktop's own 460px
   (keeping the same ~5–6% inset-to-size ratio desktop and tablet both
   already use, not a guess) and layered after the 1200px block above
   so it wins for this narrower range. The blooms sit behind .dm-window
   (z-index 0 vs. 1) and are pointer-events: none, so growing them only
   changes how much glow peeks out past the window's rounded corners —
   low risk of covering real content. Breakpoint deliberately matches
   the crop block's own 520px: these larger blooms are scaled for the
   cropped near-desktop-width window, so they should stop applying at
   exactly the width where that presentation stops. */
@media (max-width: 520px) {
  .dm-bloom-blue,
  .dm-bloom-red {
    width: 280px;
    height: 280px;
  }
  .dm-bloom-blue { top: -15px; left: -15px; }
  .dm-bloom-red { bottom: -15px; right: -15px; }
}

.dm-titlebar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 10px 16px;
  background: var(--dm-bg-inset);
  border-bottom: 1px solid var(--dm-border);
}
.dm-dots { display: flex; gap: 6px; }
.dm-dots span { width: 10px; height: 10px; border-radius: 50%; background: var(--dm-dot); display: block; }
.dm-address {
  flex: 1;
  background: var(--dm-bg-deep);
  border-radius: 6px;
  padding: 4px 12px;
  font-size: 12px;
  color: var(--dm-text-muted);
  text-align: center;
}
.dm-body { display: flex; min-height: 320px; }
.dm-rail {
  width: 56px;
  flex-shrink: 0;
  background: var(--dm-bg-outer);
  border-right: 1px solid var(--dm-border);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 16px 0;
}
.dm-rail-mark {
  width: auto;
  max-width: 24px;
  height: 24px;
  object-fit: contain;
  border-radius: 6px;
  flex-shrink: 0;
  display: block;
  margin-bottom: 6px;
}
.dm-rail-icon { color: var(--dm-text-muted); opacity: 0.65; display: flex; }
.dm-rail-icon svg { width: 17px; height: 17px; }
.dm-rail-icon-active { color: var(--accent); opacity: 1; }
.dm-main { flex: 1; padding: 16px 20px; min-width: 0; }
.dm-topbar {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 18px; font-size: 13px;
}
/* Mirrors the real admin topbar's markup exactly: the "Welcome," prefix
   is a plain <i> (italic, lighter weight, muted color), the name is <b>
   (bold, full-bright text) — see admin/partials/topbar.php + layout.css's
   .topbar-welcome b rule. */
.dm-welcome { font-size: 13px; }
.dm-welcome i { font-style: italic; font-weight: 400; color: var(--dm-text-muted); }
.dm-welcome b { font-weight: 700; color: var(--dm-text); }
.dm-topbar-icons { display: flex; align-items: center; gap: 12px; color: var(--dm-text-muted); }
.dm-bell { display: flex; }
.dm-bell svg { width: 17px; height: 17px; }
.dm-avatar {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700;
}
.dm-stats-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px;
  margin-bottom: 14px;
}
@media (min-width: 480px) { .dm-stats-grid { grid-template-columns: repeat(3, 1fr); } }
.dm-stat-card {
  background: var(--dm-bg-inset); border: 1px solid var(--dm-border);
  border-radius: 10px; padding: 10px;
}
.dm-stat-icon {
  width: 24px; height: 24px; border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 7px;
}
.dm-stat-icon svg { width: 13px; height: 13px; }
/* Each modifier maps to a real widget's exact icon_class color pairing
   from blog/admin/index.php's $dashboardWidgets array. */
.dm-stat-icon--coral { background: var(--accent-soft); color: var(--accent); }
.dm-stat-icon--green { background: var(--dm-green-soft); color: var(--dm-green); }
.dm-stat-icon--amber { background: var(--dm-amber-soft); color: var(--dm-amber); }
.dm-stat-icon--indigo { background: var(--dm-indigo-soft); color: var(--dm-indigo); }
.dm-stat-icon--purple { background: var(--dm-purple-soft); color: var(--dm-purple); }
.dm-stat-icon--blue { background: var(--dm-blue-soft); color: var(--dm-blue); }
.dm-stat-icon--teal { background: var(--dm-teal-soft); color: var(--dm-teal); }
.dm-stat-icon--fuchsia { background: var(--dm-fuchsia-soft); color: var(--dm-fuchsia); }
.dm-stat-icon--rose { background: var(--dm-rose-soft); color: var(--dm-rose); }
.dm-stat-num { font-family: var(--font-heading); font-size: 16px; font-weight: 700; color: var(--dm-text); }
.dm-stat-label { font-size: 10.5px; color: var(--dm-text-muted); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dm-chart-card {
  background: var(--dm-bg-inset); border: 1px solid var(--dm-border);
  border-radius: 10px; padding: 14px;
}
.dm-chart-title { font-size: 12px; color: var(--dm-text-muted); margin-bottom: 10px; }
.dm-chart-svg { width: 100%; height: 70px; display: block; }

/* ===== Mobile: crop-and-bleed instead of shrink-to-fit =====
   Below, .dm-window had no explicit width, so on narrow viewports the
   flex chain (.dm-rail fixed 56px + .dm-main flex:1 min-width:0) let it
   shrink-to-fit the viewport — at 375px that squeezed all 9 stat cards
   into 2 cramped columns and stretched the window to ~790px tall (vs.
   its natural ~460px), a visibly distorted "flexed" mockup rather than
   a smaller version of the real thing.
   Fix: give the window a roomy, desktop-proportioned width so nothing
   inside it ever has to reflow, then let it overflow past the
   viewport's right edge instead of shrinking. `.hero`'s own
   `overflow-x: clip` (hero.css) is what clips the excess — body's
   overflow-x: hidden was tried first and is NOT sufficient, see the
   long note there. hero.css also left-aligns the wrapper (instead of
   centering) so the crop reads as "peek at the real dashboard" rather
   than an accident.

   Width is viewport-proportional, not a fixed pixel value: at a fixed
   620px the *fraction* of the window left visible swung a lot between
   devices (52% of it on a 320px phone vs. 69% on a 430px one), so the
   hero visibly recomposed itself from phone to phone. Scaling with vw
   keeps that fraction roughly constant, so every phone gets the same
   composition. 145vw is deliberately close to the ratio both reference
   sites use at this width (tryplayground.com 1.42x viewport, vesto.com
   1.43x). The clamp floor stops the window getting narrow enough on a
   small phone to squeeze the 3-column stat grid below; the ceiling
   keeps it from outgrowing its desktop proportions on a large one.

   Capped at 520px, not 640px, so this only covers genuine phone
   widths. Between ~520 and 640 the clamp's own ceiling meant the
   window ended up only fractionally wider than the viewport (91%
   of it visible at 600px, and at exactly 640px just 16px was being
   trimmed) — a sliver-off-the-edge crop that reads as a layout bug
   rather than a deliberate bleed. Above this the window simply
   shrinks to fit uncropped, which is the honest presentation at
   those widths. Matches the .hero-title br breakpoint in hero.css so
   the hero doesn't change character in two separate places. */
@media (max-width: 520px) {
  .dm-window { width: clamp(500px, 145vw, 640px); }
  /* .dm-stats-grid's own 3-column rule is a (min-width: 480px) *viewport*
     query, so on a real ~375px phone it stays at 2 columns even though
     the window above is now a roomy 620px — 9 cards at 2-per-row runs
     to 5 rows and a needlessly tall crop. Force 3 columns here too,
     matching how it actually renders at this same width on desktop. */
  .dm-stats-grid { grid-template-columns: repeat(3, 1fr); }
}
