/* DeskKit unified product redesign — new shared UI layer.
   Deliberately a separate file from style.css: these are new,
   additive components (header, mobile nav, home, projects, create
   chooser, breadcrumb, wizard upgrades) built against the brand
   tokens already defined in style.css's :root (--primary/--text/
   --bg/--surface/--border/etc.) rather than the older --ink/--grey
   naming. Keeping them here means this pass can be reviewed, iterated
   on and cache-busted on its own without touching the already-large
   legacy stylesheet line-for-line. */

/* ============ Shared header (js/header.js) ============ */
.dk-header-links { display: flex; align-items: center; gap: 26px; font-size: 15px; font-weight: 500; }
.dk-header-links a { color: var(--text); opacity: .82; text-decoration: none; transition: opacity .15s ease; padding-block: 6px; }
.dk-header-links a:hover { opacity: 1; }
.dk-header-cta {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  background: var(--primary); color: #fff; font-weight: 700; font-size: 14px;
  border: none; border-radius: 999px; padding: 10px 20px; text-decoration: none;
  transition: background .15s ease, transform .15s ease; cursor: pointer;
}
.dk-header-cta:hover { background: var(--primary-dark); transform: translateY(-1px); }
/* Confirmed-live bug: below the breakpoint where .brand goes
   position:absolute (css/style.css's own 940px rule) and the slide-in
   nav takes over, .nav-end-group still had to fit this CTA pill AND
   the login/"Sign in" pill AND (since the EN toggle rollout) the
   lang-toggle pill, all at once, in a row already narrower than their
   combined natural width — overflowing straight across .brand's fixed
   position and visibly overlapping the DeskKit wordmark. Hidden here
   at the SAME 760px breakpoint .dk-mobile-nav (js/mobile-nav.js)
   itself uses to take over — that bottom bar's own "חשבון"/"Account"
   tab already reaches the same account.html entry point this CTA
   does, so nothing is actually lost by not showing both at once. */
@media (max-width: 760px) {
  .dk-header-cta { display: none; }
}
.dk-header-bell {
  display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px;
  border-radius: 50%; border: none; background: transparent; color: var(--text-secondary); cursor: pointer;
}
.dk-header-bell:hover { background: var(--bg); color: var(--text); }
.dk-header-avatar-wrap { position: relative; }
.dk-header-avatar {
  display: inline-flex; align-items: center; gap: 8px; background: none; border: none; cursor: pointer;
  padding: 4px 6px; border-radius: 999px; font-family: inherit; font-size: 14px; color: var(--text);
}
.dk-header-avatar:hover { background: var(--bg); }
.dk-header-avatar-circle {
  width: 30px; height: 30px; border-radius: 50%; background: var(--primary-light); color: var(--primary-dark);
  display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 13px; flex-shrink: 0;
}
.dk-header-name { max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ============ Mobile bottom nav (js/mobile-nav.js) ============ */
.dk-mobile-nav {
  display: none; position: fixed; inset-inline: 0; bottom: 0; z-index: 4000;
  background: var(--surface); border-top: 1px solid var(--border);
  padding: 6px 4px calc(env(safe-area-inset-bottom, 0px) + 4px);
  box-shadow: 0 -4px 20px rgba(13,13,20,.06);
}
.dk-mobile-nav-row { display: flex; justify-content: space-around; align-items: stretch; }
.dk-mobile-nav-item {
  display: flex; flex-direction: column; align-items: center; gap: 3px; flex: 1;
  color: var(--text-muted); text-decoration: none; font-size: 11px; font-weight: 600;
  padding: 6px 2px; border-radius: 10px; background: none; border: none; cursor: pointer; font-family: inherit;
}
.dk-mobile-nav-item svg { width: 21px; height: 21px; }
.dk-mobile-nav-item.active { color: var(--primary-dark); }
.dk-mobile-nav-item-create { color: var(--primary); }
.dk-mobile-nav-item-create .dk-mobile-nav-create-circle {
  width: 34px; height: 34px; border-radius: 50%; background: var(--primary); color: #fff;
  display: flex; align-items: center; justify-content: center; margin-bottom: 1px;
}
@media (max-width: 760px) {
  .dk-mobile-nav { display: block; }
  body.dk-has-mobile-nav { padding-bottom: 64px; }
  body.dk-has-mobile-nav .my-panel-reopen, body.dk-has-mobile-nav .my-sites-rail { display: none !important; }
  body.dk-has-mobile-nav.has-sites-rail { padding-inline-start: 0 !important; }
}
/* A Shell (sites/builder/quote-app/invoice-app) already owns the full
   viewport height and has its own mobile top tab bar — the generic
   bottom nav would just double up with it and eat canvas space. */
body.dk-has-mobile-nav:has(.bshell.active) .dk-mobile-nav { display: none; }

/* ============ Persistent app-shell sidebar (js/app-sidebar.js) ============
   Opt-in: a page sets body.dk-has-app-sidebar AND the script confirms a
   real logged-in session before actually mounting — a visitor never
   sees it flash in before the auth check resolves. Desktop only, two
   pages only (Home's logged-in view, Projects) — this is deliberately
   narrower than the old, removed my-panel.js rail (which mounted
   everywhere); Builder-Shell pages keep their own full chrome, every
   other page keeps the plain top header. Reuses the exact fixed
   position + --header-h + logical-padding technique that rail used
   (see js/app-sidebar.js's own header-height comment) — proven correct
   in RTL — under a fresh class name since that whole system was
   removed, not repurposed. */
.dk-app-sidebar {
  position: fixed; top: var(--header-h, 70px); bottom: 0; inset-inline-start: 0;
  width: var(--app-sidebar-w, 216px); overflow: visible; background: var(--surface);
  border-inline-end: 1px solid var(--border); z-index: 30;
  display: flex; flex-direction: column; gap: 2px; padding: 18px 12px;
  transition: width .18s ease;
}
/* The one scrollable piece — isolated from .dk-app-sidebar itself so its
   overflow-y:auto can't force .dk-app-sidebar's own overflow-x into auto
   too (see js/app-sidebar.js's own comment on this element for the
   confirmed-live bug that caused: the collapse toggle button, which
   intentionally pokes outside .dk-app-sidebar's edge, was getting
   clipped into a half-circle by exactly that). */
.dk-app-sidebar-scroll { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
/* Keyed off .dk-app-sidebar-mounted (added by js/app-sidebar.js only
   once a real logged-in session is confirmed and the sidebar actually
   exists in the DOM) — NOT off body.dk-has-app-sidebar, which is just
   the static per-page opt-in marker the script checks. Keying the
   layout shift off the static marker would push a logged-OUT
   visitor's whole page sideways to make room for a sidebar that was
   never actually shown. */
body.dk-app-sidebar-mounted { padding-inline-start: var(--app-sidebar-w, 216px); transition: padding-inline-start .18s ease; }
/* header.site is a normal-flow child of body, so the padding above
   would also narrow/push it — it isn't fixed-position like the
   sidebar. Counter it so the header still spans the full browser
   width above the sidebar (same counter-margin technique the old,
   removed rail used for the exact same reason). */
body.dk-app-sidebar-mounted header.site {
  margin-inline-start: calc(var(--app-sidebar-w, 216px) * -1); width: calc(100% + var(--app-sidebar-w, 216px));
  transition: margin-inline-start .18s ease, width .18s ease;
}
/* Collapse toggle (js/app-sidebar.js's own button): shrinks the one
   variable everything above already reads, instead of a parallel set
   of "collapsed" rules per property. */
body.dk-app-sidebar-collapsed { --app-sidebar-w: 70px; }
body.dk-app-sidebar-collapsed .dk-app-sidebar-item { justify-content: center; padding-inline: 0; }
body.dk-app-sidebar-collapsed .dk-app-sidebar-item-label { display: none; }
.dk-app-sidebar-toggle {
  position: absolute; top: 18px; inset-inline-end: -12px; width: 24px; height: 24px; border-radius: 50%;
  border: 1px solid var(--border-color); background: var(--bg-card); color: var(--text-muted); cursor: pointer;
  display: flex; align-items: center; justify-content: center; font-size: 13px; line-height: 1; z-index: 31;
  box-shadow: var(--shadow-sm); padding: 0;
}
.dk-app-sidebar-toggle:hover { color: var(--brand-color); border-color: var(--brand-color); }
body.dk-app-sidebar-collapsed .dk-app-sidebar-toggle { transform: scaleX(-1); }
/* A Builder Shell (sites/CV/Quote/Invoice) normally owns the full
   viewport at z-index:5000, which would simply bury the sidebar behind
   it rather than let the two coexist — so when the sidebar is mounted,
   the Shell starts after it instead of at the true edge. */
body.dk-app-sidebar-mounted .bshell.active {
  inset-inline-start: var(--app-sidebar-w, 216px); transition: inset-inline-start .18s ease;
}
@media (max-width: 900px) {
  .dk-app-sidebar { display: none; }
  body.dk-app-sidebar-mounted { padding-inline-start: 0; }
  body.dk-app-sidebar-mounted header.site { margin-inline-start: 0; width: 100%; }
  body.dk-app-sidebar-mounted .bshell.active { inset-inline-start: 0; }
}
/* .dk-sidebar-item is the same component under its shorter, globally
   documented name (the user's own requested classname) — icon and
   label sit flush together, both aligned to the same side under RTL
   (flex row + gap, no separate positioning for each), with a subtle
   background-only hover instead of a heavier border/shadow effect. */
.dk-app-sidebar-item, .dk-sidebar-item {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 10px;
  color: var(--text-secondary); text-decoration: none; font-size: 14px; font-weight: 600;
  transition: background .15s ease, color .15s ease;
}
.dk-app-sidebar-item-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dk-app-sidebar-item:hover, .dk-sidebar-item:hover { background: var(--bg); color: var(--text); }
.dk-app-sidebar-item.active, .dk-sidebar-item.active { background: var(--primary-light); color: var(--primary-dark); }
.dk-app-sidebar-icon {
  width: 30px; height: 30px; border-radius: 9px; display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; background: var(--bg); color: var(--text-secondary);
}
.dk-app-sidebar-icon svg { width: 16px; height: 16px; }
.dk-app-sidebar-divider { height: 1px; background: var(--border); margin: 10px 2px; }
.dk-app-sidebar-label { font-size: 11px; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; padding: 10px 10px 4px; }

/* Account row — pinned to the bottom of the sidebar (margin-top:auto
   in a flex column) per the user's explicit ask, instead of living in
   the top header the way it used to. The header's own copy
   (js/nav-auth.js's #nav-login-link) is hidden below once this is
   mounted, so the account only ever shows in one place at a time. */
.dk-app-sidebar-account { margin-top: auto; padding-top: 10px; border-top: 1px solid var(--border-color); position: relative; }
.dk-app-sidebar-account-toggle {
  display: flex; align-items: center; gap: 10px; width: 100%; box-sizing: border-box;
  background: none; border: none; cursor: pointer; padding: 9px 10px; border-radius: 10px;
  font-family: inherit; color: var(--text-secondary); transition: background .15s ease, color .15s ease;
}
.dk-app-sidebar-account-toggle:hover { background: var(--bg); color: var(--text); }
.dk-app-sidebar-account-email { flex: 1; min-width: 0; font-size: 13px; font-weight: 600; direction: ltr; text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.dk-app-sidebar-collapsed .dk-app-sidebar-account-email { display: none; }
body.dk-app-sidebar-collapsed .dk-app-sidebar-account-toggle { justify-content: center; padding-inline: 0; }
/* The header's own account widget (js/nav-auth.js) moves into the
   sidebar once one is mounted — same reasoning and same technique the
   old, removed my-panel.js rail used for body.has-sites-rail. */
body.dk-app-sidebar-mounted .nav-account-wrap { display: none; }

/* Per-product accent colors — shared by the sidebar's own create
   shortcuts, Home's 6 create-cards and the create-chooser modal's
   icons via data-dk-product, so the same 6 colors mean the same 6
   things everywhere (reference-image parity: colorful tiles per
   product, not one monochrome teal repeated six times). Specificity
   (attribute selector + descendant class) wins over each element's
   own plain-class default background declared elsewhere. */
[data-dk-product="site"] .dk-app-sidebar-icon, [data-dk-product="site"] .dk-home-card-icon, [data-dk-product="site"] .dk-create-opt-icon, [data-dk-product="site"] .dk-home-hero-tool-icon, [data-dk-product="site"] .dk-home-dash-tool-icon { background: #CCFBF1; color: #0F766E; }
[data-dk-product="cv"] .dk-app-sidebar-icon, [data-dk-product="cv"] .dk-home-card-icon, [data-dk-product="cv"] .dk-create-opt-icon, [data-dk-product="cv"] .dk-home-hero-tool-icon, [data-dk-product="cv"] .dk-home-dash-tool-icon { background: #EDE9FE; color: #6D28D9; }
[data-dk-product="quote"] .dk-app-sidebar-icon, [data-dk-product="quote"] .dk-home-card-icon, [data-dk-product="quote"] .dk-create-opt-icon, [data-dk-product="quote"] .dk-home-hero-tool-icon, [data-dk-product="quote"] .dk-home-dash-tool-icon { background: #FEF3C7; color: #B45309; }
[data-dk-product="invoice"] .dk-app-sidebar-icon, [data-dk-product="invoice"] .dk-home-card-icon, [data-dk-product="invoice"] .dk-create-opt-icon, [data-dk-product="invoice"] .dk-home-hero-tool-icon, [data-dk-product="invoice"] .dk-home-dash-tool-icon { background: #FFE4E6; color: #BE123C; }
[data-dk-product="deck"] .dk-app-sidebar-icon, [data-dk-product="deck"] .dk-home-card-icon, [data-dk-product="deck"] .dk-create-opt-icon, [data-dk-product="deck"] .dk-home-hero-tool-icon, [data-dk-product="deck"] .dk-home-dash-tool-icon { background: #DBEAFE; color: #1D4ED8; }
[data-dk-product="xlsx"] .dk-app-sidebar-icon, [data-dk-product="xlsx"] .dk-home-card-icon, [data-dk-product="xlsx"] .dk-create-opt-icon, [data-dk-product="xlsx"] .dk-home-hero-tool-icon, [data-dk-product="xlsx"] .dk-home-dash-tool-icon { background: #DCFCE7; color: #15803D; }

/* Project-card thumbnail strip: same per-product color, as a soft
   gradient wash with a large faint watermark icon — a real preview of
   the product rather than a flat icon chip, without relying on
   unlicensed stock photography or a screenshot pipeline that doesn't
   exist yet (a feature, not a visual-pass change). */
[data-dk-product="site"] .dk-pcard-thumb { background: linear-gradient(135deg, #CCFBF1, var(--bg-card)); }
[data-dk-product="site"] .dk-pcard-thumb-icon { color: #0F766E; }
[data-dk-product="cv"] .dk-pcard-thumb { background: linear-gradient(135deg, #EDE9FE, var(--bg-card)); }
[data-dk-product="cv"] .dk-pcard-thumb-icon { color: #6D28D9; }
[data-dk-product="quote"] .dk-pcard-thumb { background: linear-gradient(135deg, #FEF3C7, var(--bg-card)); }
[data-dk-product="quote"] .dk-pcard-thumb-icon { color: #B45309; }
[data-dk-product="invoice"] .dk-pcard-thumb { background: linear-gradient(135deg, #FFE4E6, var(--bg-card)); }
[data-dk-product="invoice"] .dk-pcard-thumb-icon { color: #BE123C; }
[data-dk-product="deck"] .dk-pcard-thumb { background: linear-gradient(135deg, #DBEAFE, var(--bg-card)); }
[data-dk-product="deck"] .dk-pcard-thumb-icon { color: #1D4ED8; }
[data-dk-product="xlsx"] .dk-pcard-thumb { background: linear-gradient(135deg, #DCFCE7, var(--bg-card)); }
[data-dk-product="xlsx"] .dk-pcard-thumb-icon { color: #15803D; }

/* ============ Create-chooser modal (js/create-chooser.js) ============ */
.dk-create-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin: 18px 0 20px; }
@media (max-width: 480px) { .dk-create-grid { grid-template-columns: 1fr; } }
.dk-create-opt {
  display: flex; align-items: center; gap: 12px; text-align: start; background: var(--bg);
  border: 1.5px solid var(--border); border-radius: 14px; padding: 14px 16px; cursor: pointer;
  font-family: inherit; color: var(--text); transition: border-color .15s ease, background .15s ease;
}
.dk-create-opt:hover { border-color: var(--primary); background: var(--surface); box-shadow: var(--shadow); }
.dk-create-opt-icon {
  width: 40px; height: 40px; border-radius: 12px; font-size: 19px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; background: var(--primary-light); color: var(--primary-dark);
}
.dk-create-opt-title { font-weight: 700; font-size: 14.5px; display: block; }
.dk-create-opt-sub { font-size: 12px; color: var(--text-secondary); display: block; margin-top: 2px; }
.dk-create-unsure { border-top: 1px solid var(--border); margin-top: 6px; padding-top: 18px; }
.dk-create-unsure label { display: block; font-weight: 700; font-size: 13.5px; margin-bottom: 8px; }
.dk-create-unsure textarea {
  width: 100%; box-sizing: border-box; border: 1.5px solid var(--border); border-radius: 12px;
  padding: 12px 14px; font-family: inherit; font-size: 14px; resize: vertical; min-height: 72px;
}
.dk-create-unsure textarea:focus { outline: none; border-color: var(--primary); }
.dk-create-unsure-btn { width: 100%; margin-top: 10px; }

/* ============ Shared buttons/primitives reused across new screens ============ */
.dk-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: inherit; font-weight: 700; font-size: 15px; border-radius: 12px; cursor: pointer;
  border: none; padding: 13px 26px; min-height: 48px; transition: background .15s ease, transform .15s ease, box-shadow .15s ease;
  text-decoration: none;
}
.dk-btn-primary { background: var(--primary); color: #fff; }
.dk-btn-primary:hover { background: var(--primary-dark); }
.dk-btn-ghost { background: var(--surface); color: var(--text); border: 1.5px solid var(--border); }
.dk-btn-ghost:hover { border-color: var(--primary); color: var(--primary-dark); }
.dk-btn-lg { padding: 15px 34px; font-size: 16px; }
.dk-pill { display: inline-flex; align-items: center; gap: 6px; background: var(--primary-light); color: var(--primary-dark); font-weight: 700; font-size: 12.5px; border-radius: 999px; padding: 5px 13px; }

/* ============ Breadcrumb (all Builder-Shells) ============ */
.dk-crumb { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 38vw; }
.dk-crumb a { color: var(--text-secondary); text-decoration: none; }
.dk-crumb a:hover { color: var(--primary-dark); text-decoration: underline; }
.dk-crumb-sep { opacity: .55; }
.dk-crumb-current { color: var(--text); font-weight: 700; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 760px) { .dk-crumb { max-width: 46vw; font-size: 12px; } }

/* ============ New Home page ============ */
body.dk-home { background: var(--bg-main); }
/* Hero: headline+CTAs+quick-create icons anchored to the reading-start
   side (right, in RTL — first in source order so it's the primary
   focus), a browser-chrome mockup of the product on the other side.
   Both sit above the fold together — the "why DeskKit" section below
   only shows once the visitor scrolls past this, matching the
   reference mockup's "at first you only see the hero" framing. */
.dk-home-hero {
  padding: 64px 0 56px; overflow: hidden;
  /* White at the top fading into a stronger, more saturated cyan
     toward the bottom — the reference mockup's own gradient reads
     white behind the navbar/headline and visibly more blue lower
     down (behind/around the laptop), the opposite direction from
     the previous cyan-at-top wash. */
  background: linear-gradient(180deg, #ffffff 0%, #eaf8fb 35%, #c9ecf4 100%);
}
/* Sized to its own content (text+laptop+tools), not forced to fill the
   viewport — a min-height tied to 100vh read fine on a typical laptop
   screen, where the content's natural height happened to be close to
   the viewport height, but on a taller monitor the gap between content
   and viewport bottom showed up as a long stretch of empty gradient
   below the laptop before "why DeskKit" appeared — confirmed live and
   reported as the cyan area being "too long" on scroll. */
@media (min-width: 681px) {
  .dk-home-hero { padding: 56px 0 32px; }
  .dk-home-hero .container { width: 100%; }
}
/* Contained + centered at 1280px (the user's own explicit ask), same
   width the navbar now uses — not the sitewide .container's 1120px,
   so this doesn't also reflow every other page. */
.dk-home-hero .container { max-width: var(--max-wide); }
/* Two zones — a "stage" (text, then a large bottom-weighted laptop
   below it) on the reading-start side (right, in RTL) + a narrow
   single-column tool list on the far side (left) — matching the
   user's reference mockup exactly, characterized from the image
   itself rather than guessed: NOT 3 equal flat columns, and the
   sidebar is a single column of six generously-sized cards, not a
   2-column grid of small tiles. DOM order is stage, tools — RTL's
   default flex flow alone gives the right visual order. */
.dk-home-hero-inner { display: flex; align-items: flex-start; gap: 40px; }
.dk-home-hero-stage { flex: 1; min-width: 0; container-type: inline-size; }
/* z-index + relative: guarantees the headline/CTA/watch-link always
   paint ABOVE the laptop photo, regardless of how much their boxes
   overlap. Needed because the photo isn't mirror-symmetric (its real
   bezel/lid pixels, not just its bounding box, are asymmetric) — in
   RTL the overlap zone (see .dk-home-hero-visual's own comment on the
   direction-aware shift) happens to land on a transparent part of the
   photo, but in LTR the equivalent zone lands on the laptop's actual
   opaque lid, which was confirmed live to visibly cover/cut off the
   CTA button and watch-link text. This doesn't fix the composition
   (the laptop now tucks fully behind the text there instead), but it
   guarantees the text itself always stays fully readable and
   clickable in both directions rather than silently depending on
   which part of an asymmetric photo the overlap zone happens to hit. */
.dk-home-hero-text { max-width: 480px; position: relative; z-index: 1; }
.dk-home-hero-text h1 { font-size: 38px; font-weight: 700; line-height: 1.3; margin: 0 0 16px; color: var(--text-main); font-family: Heebo, Arial, sans-serif; }
.dk-home-hero-text p { font-size: 16px; color: #475569; line-height: 1.6; margin: 0 0 24px; }
.dk-home-hero-ctas { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; margin-bottom: 14px; }
/* Richer gradient fill + its own soft shadow for the hero's primary
   CTA specifically — .dk-btn-primary's flat fill stays the sitewide
   default everywhere else; this scoped override matches the
   reference mockup's own button without changing every other button
   on the site. */
.dk-home-hero-ctas .dk-btn-primary {
  background: linear-gradient(135deg, var(--brand-color), var(--brand-dark)); border: none;
  box-shadow: 0 8px 16px -4px rgba(15, 118, 110, .35);
}
.dk-home-hero-ctas .dk-btn-primary:hover { background: linear-gradient(135deg, var(--brand-dark), var(--brand-dark)); }
/* The "watch how it works" link sits on its own row below the CTA
   button in the reference, not beside it. */
.dk-home-hero-watch {
  display: inline-flex; align-items: center; gap: 9px; color: var(--text-main); font-weight: 700; font-size: 14.5px; text-decoration: none;
}
.dk-home-hero-watch:hover .dk-home-hero-play { background: var(--brand-color); color: #fff; }
.dk-home-hero-play {
  width: 32px; height: 32px; border-radius: 50%; background: var(--bg-card); border: 1px solid var(--border-color);
  display: flex; align-items: center; justify-content: center; font-size: 11px; transition: background .15s ease, color .15s ease;
}

/* Tool cards — a single column of six generously-sized cards (not a
   2-col grid of small tiles), icon on the physical left / label on
   the physical right regardless of RTL (row-reverse — the reference
   itself places them this way), colorful rounded icon square, soft
   shadow, airy padding. */
.dk-home-hero-tools { flex: 0 0 260px; display: flex; flex-direction: column; gap: 14px; }
.dk-home-hero-tool {
  display: flex; flex-direction: row-reverse; align-items: center; gap: 14px;
  background: var(--bg-card); border-radius: 18px; padding: 16px 18px; text-decoration: none; color: var(--text-main);
  font-size: 15px; font-weight: 700;
  box-shadow: var(--shadow-card);
  transition: box-shadow .15s ease, transform .15s ease;
}
.dk-home-hero-tool:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.dk-home-hero-tool-icon {
  width: 42px; height: 42px; border-radius: 12px; flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  background: var(--primary-light); color: var(--primary-dark);
  box-shadow: 0 4px 10px rgba(15, 23, 42, .08);
}
.dk-home-hero-tool-icon svg { width: 22px; height: 22px; }

/* Visual: the real laptop photo the user supplied, cut to a
   transparent PNG (images/laptop-hero.png) — no background box of
   its own to clash with the page. Pulled up to tuck under the text
   block so the two read as one integrated composition instead of
   two stacked blocks with a gap, matching the reference mockup. */
/* position:relative + the leftward translateX both live on the wrapper
   now (not the <img> alone), so the screen-text overlay below —
   positioned with percentages relative to this same box — tracks the
   photo's shift as one unit instead of needing its own copy of every
   translateX value kept in sync by hand across all 3 breakpoints.

   The leftward pull itself is a formula, not a fixed px value — found
   (via direct measurement, not guessing) that this box sits flush
   against the STAGE's own right edge by default (RTL's block default),
   so a fixed translateX(-170px) is only safe once the stage is wide
   enough to have 170px of real slack past the image's own 640px
   max-width; at narrower-but-still-"desktop" widths (confirmed broken
   live from ~700px to ~1100px) that same -170px drove the photo
   straight into the tools sidebar cards, reading as the laptop being
   "cut off" by them — a real layout bug the user's repeated "still
   clipped" reports were catching, not a rendering artifact. Formula:
   safe shift = clamp(0px, stageWidth - 656px, 170px), using the
   .dk-home-hero-stage container's own inline-size (100cqw inside a
   container-type:inline-size ancestor, see .dk-home-hero-stage above)
   — 656px = the image's own 640px max-width + a 16px buffer so it
   never sits flush against the stage's own left edge (where the tools
   gap begins). Below 640px of stage width the image is no longer
   capped at 640px and fills the stage exactly (zero slack either way),
   so the clamp correctly floors the shift at 0 there too — one
   continuous formula covers both regimes, no separate breakpoint
   value needed (replacing the old 860px-breakpoint override below). */
.dk-home-hero-visual {
  width: 100%; max-width: 640px; margin-top: var(--dk-hero-margin-top, -250px); position: relative;
  /* translateX is always a PHYSICAL shift (never direction-aware on its
     own) — confirmed-live bug this caused: toggling to English flips
     the page to dir="ltr", which also flips which physical edge this
     box sits flush against by default (RTL: flush-right, so shifting
     left pulls it toward the tools column on the physical left; LTR:
     flush-left instead, so that same leftward shift pulled it further
     away from the stage's own box and off the left edge of the
     viewport entirely — "jumps to the side"). The shift amount itself
     (the clamp() formula, explained below) is direction-agnostic and
     correct either way; only its SIGN needs to flip with the page
     direction, via this custom property. */
  --dk-hero-shift: clamp(0px, (100cqw - 656px), var(--dk-hero-shift-cap, 170px));
  transform: translateX(calc(-1 * var(--dk-hero-shift)));
  container-type: inline-size;
}
/* LTR needs its own tuning, not just the RTL numbers with the sign
   flipped — the laptop photo itself is a real photograph, not a
   mirror-symmetric graphic, so its own opaque silhouette (the dark
   lid/bezel) sits in a DIFFERENT place relative to the text once the
   whole composition flips. In RTL, the horizontal shift happens to
   carry that opaque area away from where the text sits; in LTR the
   same shift (even sign-flipped) carried it UNDER the text instead —
   confirmed live as the laptop visibly covering the CTA button and
   watch-link text, not just a boxes-overlap technicality. Verified by
   directly measuring the text block's own real height in English
   (longer line-wrapping than Hebrew) and solving for a margin-top that
   clears it, then increasing the horizontal cap so the image also
   moves further past the text block's own right edge — together, not
   either alone (checked: horizontal distance alone can't clear the
   opaque corner within the tools-sidebar-safe shift budget, and
   vertical clearance alone would undo nearly all of the intentional
   "tucked under the text" composition, since this box's natural,
   margin-top:0 position already starts flush at the text's own bottom
   edge with zero built-in gap in EITHER direction — RTL's working
   look was never from spare room, only from where the shift happened
   to land on the photo). */
/* Both --dk-hero-margin-top and --dk-hero-shift above were fixed
   numbers (-150px / 260px) tuned only for wide desktop, where
   --dk-hero-shift is already pinned at its cap. Confirmed-live bug this
   caused: at in-between widths (~900-1250px, a completely normal laptop
   screen, not a breakpoint edge case) the clamp() hasn't reached that
   cap yet, so the horizontal shift is smaller — but the vertical pull
   was still the full fixed -150px regardless, so the laptop's opaque
   lid sat UNDER "Watch how it works" with no horizontal clearance to
   carry it away. Fix: margin-top now scales down together with the
   SAME (100cqw - 656px) term the shift itself uses, so it only reaches
   its full -150px tuck once the shift has actually reached a cap worth
   tucking under, and sits flush (0 overlap) at the narrow end where
   there's no horizontal clearance yet — same formula family, kept in
   sync by construction instead of as two numbers that can drift apart.
   -0.559 = -190px / 340px (this rule's own cap/pull pair, below), so
   both reach their max together at the same cqw. Cap raised again
   (300->340px, shift further right toward the tools column) and the
   max vertical pull raised too (-150->-190px, tucks the photo higher)
   per repeated "move it right toward the tools buttons, raise it
   higher, there's still room" reports — reverified at 1024-1920px
   that this neither collides with the tools column (checked each
   width's own gap to .dk-home-hero-tools) nor gets clipped by this
   section's own overflow:hidden bottom edge (checked each width's own
   image-bottom vs hero-bottom). */
html[dir="ltr"] .dk-home-hero-visual {
  --dk-hero-margin-top: clamp(-280px, calc(-0.823 * (100cqw - 656px)), 0px);
  --dk-hero-shift-cap: 380px;
  transform: translateX(var(--dk-hero-shift));
}
.dk-home-hero-laptop-img {
  width: 100%; display: block;
  filter: drop-shadow(0 25px 35px rgba(0, 0, 0, .12)) drop-shadow(0 8px 10px rgba(0, 0, 0, .08));
  /* Decorative only (aria-hidden) — without this, the image's full
     rectangular box (transparent PNG areas included) sits on top of
     and intercepts clicks on the "watch how it works" link above it,
     since it paints after that sibling in normal flow. Confirmed live
     via elementFromPoint at the link's own coordinates returning this
     <img>, not the link. */
  pointer-events: none;
}
/* Sits inside the laptop photo's own screen glass, warped to the
   screen's real tilted plane instead of just rotated flat — a flat
   rotate() stood the text "upright" while the screen itself recedes
   in perspective (its right edge closer/lower than its left), so the
   text read as floating in front of the glass rather than printed on
   it. Fixed with a true perspective (homography) transform: this box
   is laid out as a normal flat 480x380 design canvas, then
   matrix3d() warps its 4 corners onto the screen's real 4 corners —
   computed via cv2.getPerspectiveTransform from the screen quad found
   by OpenCV contour detection on the source PNG (corners roughly
   (26,173)/(613,206)/(672,631)/(83,659) in the 1024x946 image, shrunk
   14% inward for bezel margin). matrix3d's translate components are
   always real pixels in the element's own box, never %, so they're
   only correct at the image's native 1024px width — the leading
   scale() converts from that fixed native-pixel space down to
   whatever size the (fully responsive) photo is actually rendered
   at, via `100cqw` (container query width = this element's own
   current rendered width, see container-type:inline-size on
   .dk-home-hero-visual above) divided by 1024px, which is a plain
   ratio: no resize listener/JS needed, and both transforms stay
   correct together at every breakpoint from one set of numbers. */
.dk-home-hero-screen-overlay {
  position: absolute; top: 0; left: 0; width: 480px; height: 380px;
  transform-origin: 0 0;
  transform: scale(calc(100cqw / 1024px)) matrix3d(
    1.222539, 0.128996, 0, 0.000297,
    0.123416, 1.070847, 0, -0.000046,
    0, 0, 1, 0,
    71.150002, 207.195007, 0, 1
  );
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px;
  text-align: center;
}
.dk-home-hero-screen-overlay p {
  margin: 0; font-weight: 800; line-height: 1.22; color: var(--text-main, #0F172A);
  font-size: 42px; font-family: Heebo, Arial, sans-serif;
}
.dk-home-hero-screen-cta {
  display: inline-flex; align-items: center; gap: 10px; text-decoration: none; white-space: nowrap;
  background: linear-gradient(135deg, var(--brand-color), var(--brand-dark)); color: #fff;
  font-weight: 700; font-size: 21px; padding: 14px 30px;
  border-radius: 999px; box-shadow: 0 6px 14px -4px rgba(15, 118, 110, .4);
}

@media (max-width: 860px) {
  .dk-home-hero-inner { flex-direction: column; align-items: center; }
  .dk-home-hero-stage { width: 100%; }
  .dk-home-hero-tools { flex: none; width: 100%; max-width: 420px; }
  /* The formula above (base rule) is only valid for the side-by-side
     desktop layout, where it solves for the stage's width as
     container-minus-tools-minus-gap; once the layout stacks to a
     single centered column here, the stage is ~the full container
     width instead, which would make that same formula compute a large
     leftward shift that just pushes the laptop off-center/off the left
     edge of the viewport — a flat, small nudge is the correct behavior
     in this stacked layout, not the formula. Still direction-aware
     (see the base rule above) since translateX itself never is. */
  .dk-home-hero-visual { --dk-hero-shift: 20px; transform: translateX(calc(-1 * var(--dk-hero-shift))); }
  html[dir="ltr"] .dk-home-hero-visual { transform: translateX(var(--dk-hero-shift)); }
}
@media (max-width: 680px) {
  .dk-home-hero { padding: 40px 0 36px; }
  .dk-home-hero-text h1 { font-size: 30px; }
  .dk-home-hero-text p { font-size: 15.5px; max-width: none; }
  .dk-home-hero-visual { margin-top: -10px; transform: none; }
}

/* ============ "Why DeskKit" — first thing visible after the hero on
   scroll, matching the reference mockup's below-the-fold framing. ============ */
/* Top padding specifically: the hero's own gradient now ends in a
   fairly saturated cyan right at this section's top edge, and with
   zero top padding the icon cards sat flush against that seam,
   reading as glued to the gradient above instead of a separate
   section. */
.dk-home-why { padding: 56px 0 64px; }
.dk-home-why-grid { max-width: 1120px; margin: 0 auto; display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
@media (max-width: 860px) { .dk-home-why-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .dk-home-why-grid { grid-template-columns: 1fr; } }
.dk-home-why-item { text-align: center; }
.dk-home-why-icon {
  width: 52px; height: 52px; border-radius: 15px; background: var(--primary-light); color: var(--primary-dark);
  display: flex; align-items: center; justify-content: center; margin: 0 auto 14px;
}
.dk-home-why-icon svg { width: 24px; height: 24px; }
.dk-home-why-item h4 { margin: 0 0 6px; font-size: 16px; font-weight: 700; color: var(--text-main); }
.dk-home-why-item p { margin: 0; font-size: 13.5px; color: var(--text-secondary); line-height: 1.55; }

.dk-home-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin: 0 0 56px; }
@media (max-width: 980px) { .dk-home-cards { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .dk-home-cards { grid-template-columns: 1fr; } }
.dk-home-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 18px; padding: 26px 22px;
  text-decoration: none; color: var(--text); display: flex; flex-direction: column; gap: 10px;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; cursor: pointer;
}
.dk-home-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--primary); }
.dk-home-card-icon {
  width: 46px; height: 46px; border-radius: 13px; background: var(--primary-light); color: var(--primary-dark);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.dk-home-card-icon svg { width: 22px; height: 22px; }
.dk-home-card h3 { margin: 0; font-size: 18px; font-weight: 700; }
.dk-home-card p { margin: 0; font-size: 13.5px; color: var(--text-secondary); line-height: 1.6; flex: 1; }
.dk-home-card-cta { font-size: 13.5px; font-weight: 700; color: var(--primary-dark); }

.dk-home-freetext { max-width: 680px; margin: 0 auto 60px; text-align: center; }
.dk-home-freetext-eyebrow { display: block; font-weight: 700; color: var(--primary-dark); margin-bottom: 10px; font-size: 14.5px; }
.dk-home-freetext-row { display: flex; gap: 10px; background: var(--surface); border: 1.5px solid var(--border); border-radius: 16px; padding: 10px; box-shadow: var(--shadow); }
.dk-home-freetext-row textarea {
  /* min-height was 26px — barely one line, so this box's own placeholder
     text (3 lines in English: "Tell me what you'd like to create... for
     example: I'm starting a new business...") rendered visibly clipped,
     its last line cut off by the textarea's own bottom edge rather than
     wrapping into view — confirmed live, not a rendering artifact. Tall
     enough for 3 real lines at this font-size/line-height now, in
     either language. */
  flex: 1; border: none; resize: none; font-family: inherit; font-size: 15px; min-height: 84px; max-height: 120px;
  padding: 10px 12px; background: transparent;
}
.dk-home-freetext-row textarea:focus { outline: none; }
.dk-home-freetext-row button { flex-shrink: 0; align-self: flex-end; }
/* Side-by-side wastes most of the row's width on a cramped button at
   mobile widths, which is exactly what forced the placeholder down to 4+
   wrapped lines in the first place (narrower textarea = more lines) —
   confirmed live as the last line still clipped even after widening
   min-height above, since that fix sized for 3 lines, not 4. Stacked
   instead: the textarea gets the row's FULL width (fewer wrapped lines)
   and its own min-height still has real headroom, with the button on its
   own full-width line below rather than squeezed beside the text. */
@media (max-width: 560px) {
  .dk-home-freetext-row { flex-direction: column; }
  .dk-home-freetext-row button { align-self: stretch; }
}

.dk-home-section { max-width: 1120px; margin: 0 auto; padding: 0 20px 64px; }
.dk-home-section-head { text-align: center; margin-bottom: 32px; }
.dk-home-section-head h2 { font-size: 30px; font-weight: 700; margin: 0 0 10px; color: var(--text); }
.dk-home-section-head p { font-size: 15.5px; color: var(--text-secondary); margin: 0; }
.dk-home-groups { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
@media (max-width: 860px) { .dk-home-groups { grid-template-columns: 1fr; } }
.dk-home-group { background: var(--surface); border: 1px solid var(--border); border-radius: 16px; padding: 22px; }
.dk-home-group h4 { margin: 0 0 8px; font-size: 15.5px; font-weight: 700; color: var(--primary-dark); }
.dk-home-group p { margin: 0; font-size: 13.5px; color: var(--text-secondary); line-height: 1.8; }

.dk-home-steps { display: flex; gap: 22px; justify-content: center; flex-wrap: wrap; }
.dk-home-step { flex: 1; min-width: 200px; max-width: 280px; text-align: center; }
.dk-home-step-num {
  width: 46px; height: 46px; border-radius: 50%; background: var(--primary); color: #fff; font-weight: 800;
  font-size: 17px; display: flex; align-items: center; justify-content: center; margin: 0 auto 14px;
}
.dk-home-step h4 { margin: 0 0 6px; font-size: 15.5px; }
.dk-home-step p { margin: 0; font-size: 13.5px; color: var(--text-secondary); line-height: 1.7; }

.dk-home-wow {
  background: linear-gradient(180deg, var(--primary-light) 0%, var(--bg) 100%);
  border-radius: 22px; padding: 44px 24px; max-width: 1080px; margin: 0 auto 64px;
}
.dk-home-wow-pipe { display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap; }
.dk-home-wow-node {
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 14px 18px;
  font-size: 13.5px; font-weight: 700; color: var(--text); min-width: 110px; text-align: center;
  box-shadow: var(--shadow); animation: dkWowPulse 3.2s ease-in-out infinite;
}
.dk-home-wow-node:nth-child(3) { animation-delay: .4s; }
.dk-home-wow-node:nth-child(5) { animation-delay: .8s; }
.dk-home-wow-node:nth-child(7) { animation-delay: 1.2s; }
.dk-home-wow-node:nth-child(9) { animation-delay: 1.6s; }
.dk-home-wow-arrow { color: var(--primary-dark); font-size: 18px; flex-shrink: 0; }
@keyframes dkWowPulse { 0%,100% { transform: translateY(0); box-shadow: var(--shadow); } 50% { transform: translateY(-4px); box-shadow: var(--shadow-lg); } }
@media (prefers-reduced-motion: reduce) { .dk-home-wow-node { animation: none; } }
@media (max-width: 760px) { .dk-home-wow-pipe { flex-direction: column; } .dk-home-wow-arrow { transform: rotate(90deg); } }

/* Logged-in home variant (the Dashboard) — same contained width
   (--max-wide) and card language (shadow-sm, radius-md, per-product
   icon colors) the Home hero and Projects page already use, so this
   doesn't read as a separate, lower-effort screen bolted onto the
   same product. */
.dk-home-dash { max-width: var(--max-wide); margin: 0 auto; padding: 48px 32px 64px; }
.dk-home-dash-greet h1 { font-size: 32px; font-weight: 800; margin: 0 0 6px; color: var(--text-main); }
.dk-home-dash-greet p { font-size: 16px; color: #475569; margin: 0 0 32px; }
.dk-home-dash-tools { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 48px; }
.dk-home-dash-tool {
  display: flex; flex-direction: column; align-items: center; gap: 10px; width: 108px; box-sizing: border-box;
  background: var(--bg-card); border: 1px solid var(--border-color); border-radius: var(--radius-md);
  padding: 18px 10px; text-decoration: none; color: var(--text-main); font-size: 13px; font-weight: 700;
  box-shadow: var(--shadow-card);
  transition: box-shadow .15s ease, transform .15s ease, border-color .15s ease;
}
.dk-home-dash-tool:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); border-color: var(--brand-color); }
.dk-home-dash-tool-icon {
  width: 44px; height: 44px; border-radius: 12px; display: flex; align-items: center; justify-content: center;
  background: var(--primary-light); color: var(--primary-dark);
}
.dk-home-dash-tool-icon svg { width: 22px; height: 22px; }
.dk-home-recent-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.dk-home-recent-head h2 { font-size: 21px; margin: 0; }
.dk-home-recent-head a { font-size: 13.5px; font-weight: 700; color: var(--primary-dark); text-decoration: none; }

/* ============ Shared project card (Home-recent + Projects page + My Websites) ============
   Rebuilt in the visual-design pass: white bg-card, soft shadow-md,
   generous 24px padding, colorful icon badge top-start, 3-dot menu
   top-end, clean CTA pinned to the bottom — replacing the old flat
   color-square thumbnail with the reference mockup's card language. */
.dk-pcard-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 20px; }
.dk-pcard {
  background: var(--bg-card); border: 1px solid var(--border-color); border-radius: var(--radius-md);
  overflow: hidden; display: flex; flex-direction: column; position: relative;
  box-shadow: var(--shadow-card);
  transition: box-shadow .15s ease, transform .15s ease;
}
.dk-pcard:hover { box-shadow: var(--shadow-lg); transform: translateY(-2px); }
.dk-pcard-thumb { position: relative; height: 108px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
.dk-pcard-thumb-icon { width: 44px; height: 44px; opacity: .55; }
.dk-pcard-thumb-icon svg { width: 100%; height: 100%; }
.dk-pcard-body { padding: 18px 20px 20px; display: flex; flex-direction: column; flex: 1; }
.dk-pcard-name { font-weight: 700; font-size: 16px; margin: 0 0 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dk-pcard-meta { font-size: 12.5px; color: var(--text-muted); margin: 0 0 4px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-height: 18px; }
.dk-pcard-status { display: inline-flex; align-items: center; gap: 4px; font-weight: 700; }
.dk-pcard-status::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--text-muted); }
.dk-pcard-status.live::before { background: var(--success); }
.dk-pcard-status.draft::before { background: var(--warning); }
.dk-pcard-date { font-size: 12px; color: var(--text-muted); margin: 0 0 18px; }
/* Small, pill-shaped, sized to its own text — pinned to the card's
   bottom-left corner (align-self: flex-end resolves to inline-end,
   the visual left edge under RTL) instead of stretching the full
   card width, per the user's explicit "too wide, make it a small
   elegant corner button" correction. */
.dk-pcard-cta {
  margin-top: auto; align-self: flex-end; display: inline-flex; align-items: center; justify-content: center;
  padding: 8px 18px; border-radius: 999px; background: var(--brand-color);
  color: #fff; font-size: 12.5px; font-weight: 700; text-decoration: none;
  transition: background .15s ease, transform .15s ease;
}
.dk-pcard-cta:hover { background: var(--brand-dark); transform: translateY(-1px); }
.dk-pcard-more {
  position: absolute; top: 10px; inset-inline-end: 10px; width: 30px; height: 30px; border-radius: 8px; border: none;
  background: rgba(255, 255, 255, .82); cursor: pointer; color: var(--text-main); font-size: 17px; line-height: 1;
  display: flex; align-items: center; justify-content: center; transition: background .15s ease;
}
.dk-pcard-more:hover { background: #fff; }
.dk-pcard-menu {
  position: absolute; inset-inline-end: 16px; top: 104px; background: var(--bg-card); border: 1px solid var(--border-color);
  border-radius: 10px; box-shadow: var(--shadow-lg); min-width: 150px; z-index: 20; overflow: hidden;
}
.dk-pcard-menu button { display: block; width: 100%; text-align: start; background: none; border: none; padding: 10px 14px; font-size: 13px; font-family: inherit; color: var(--text); cursor: pointer; }
.dk-pcard-menu button:hover { background: var(--bg-main); }
.dk-pcard-menu button.danger { color: var(--error); }
.dk-pcard-empty { grid-column: 1/-1; text-align: center; padding: 50px 20px; color: var(--text-secondary); }
.dk-pcard-empty a { color: var(--primary-dark); font-weight: 700; }
/* A failed fetch, not a genuine "zero items" state (see
   js/projects.js's dkProjectsRender) — a distinct warm tint so it never
   reads as the plain, calm empty state. */
.dk-pcard-empty.dk-pcard-error { color: #B45309; background: #FEF3C7; border-radius: 14px; }
.dk-pcard-empty.dk-pcard-error a { color: #92400E; }

/* ============ Projects page ============ */
.dk-projects-wrap { max-width: 1120px; margin: 0 auto; padding: 38px 20px 80px; }
.dk-projects-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 14px; margin-bottom: 22px; }
.dk-projects-head h1 { font-size: 28px; margin: 0; }
.dk-tabs { display: flex; gap: 6px; margin-bottom: 24px; flex-wrap: wrap; border-bottom: 1px solid var(--border); padding-bottom: 2px; }
.dk-tab { background: none; border: none; font-family: inherit; font-size: 14px; font-weight: 700; color: var(--text-secondary); padding: 10px 14px; cursor: pointer; border-radius: 10px 10px 0 0; position: relative; }
.dk-tab:hover { color: var(--text); }
.dk-tab.active { color: var(--primary-dark); }
.dk-tab.active::after { content: ""; position: absolute; bottom: -3px; inset-inline: 10px; height: 3px; background: var(--primary); border-radius: 3px; }

/* ============ My Websites / Website Creation Flow screens (sites.html) ============ */
.dk-sites-intro { max-width: 720px; margin: 54px auto 70px; text-align: center; padding: 0 20px; }
.dk-sites-intro h1 { font-size: 36px; margin: 0 0 14px; }
.dk-sites-intro p.lead { font-size: 16.5px; color: var(--text-secondary); line-height: 1.7; margin: 0 0 22px; }
.dk-sites-intro-facts { display: flex; justify-content: center; gap: 22px; flex-wrap: wrap; margin-bottom: 30px; font-size: 13.5px; color: var(--text-secondary); }
.dk-sites-intro-facts span { display: inline-flex; align-items: center; gap: 6px; }

.dk-mysites-wrap { max-width: 1120px; margin: 0 auto; padding: 38px 20px 80px; }
.dk-mysites-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 22px; flex-wrap: wrap; gap: 14px; }
.dk-mysites-head h1 { font-size: 28px; margin: 0; }

/* ============ Free-text-first creation intro (quote-app.html / invoice-app.html) ============
   Same visual language as .dk-sites-intro, plus the one free-text box
   itself -- Quote/Invoice are simple enough that "answer 6 questions"
   (Sites' own wizard) would be overkill; one sentence is enough for
   the AI draft to work from. */
.dk-form-intro { max-width: 640px; margin: 54px auto 70px; text-align: center; padding: 0 20px; }
.dk-form-intro h1 { font-size: 34px; margin: 0 0 12px; }
.dk-form-intro p.lead { font-size: 16px; color: var(--text-secondary); line-height: 1.7; margin: 0 0 26px; }
.dk-form-intro-textarea {
  width: 100%; box-sizing: border-box; border: 1.5px solid var(--border); border-radius: 12px;
  padding: 14px 16px; font-family: inherit; font-size: 15px; resize: vertical; min-height: 84px;
  margin-bottom: 16px;
}
.dk-form-intro-textarea:focus { outline: none; border-color: var(--primary); }
.dk-form-intro .ai-limit-note { max-width: 520px; margin: 14px auto 0; text-align: start; }
.dk-intro-skip {
  display: block; margin: 18px auto 0; background: none; border: none; cursor: pointer;
  font-family: inherit; font-size: 13.5px; color: var(--text-secondary); text-decoration: underline;
}
.dk-intro-skip:hover { color: var(--text); }
.qa-intro-style-label { font-size: 12.5px; font-weight: 700; color: var(--text-secondary); margin: 0 0 8px; text-align: start; }
/* Exactly 4 real quote styles (QUOTE_TEMPLATES) — 2 columns reads
   cleaner than .dk-style-grid's default 3 (which leaves an odd 4th
   chip alone on its own row). */
#qa-intro-style-row.dk-style-grid { grid-template-columns: repeat(2, 1fr); margin-bottom: 18px; }
/* AI draft is the secondary, opt-in option on this screen (see
   js/quote-ai-generate.js's own comment on #qa-intro-start-btn) —
   collapsed by default behind this toggle rather than shown open, so it
   reads as "optional extra", not a second equally-weighted choice. */
.dk-intro-ai-toggle {
  display: block; margin: 20px auto 0; background: none; border: none; cursor: pointer;
  font-family: inherit; font-size: 13.5px; color: var(--text-secondary); text-decoration: underline;
}
.dk-intro-ai-toggle:hover { color: var(--text); }
.dk-intro-ai-panel { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border); }

/* Wizard enhancements: style-choice visual chips */
.dk-style-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
@media (max-width: 560px) { .dk-style-grid { grid-template-columns: repeat(2, 1fr); } }
.dk-style-chip {
  border: 2px solid var(--border); border-radius: 14px; padding: 14px 10px; text-align: center; cursor: pointer;
  background: var(--surface); font-family: inherit; transition: border-color .15s ease, background .15s ease;
}
.dk-style-chip:hover { border-color: var(--primary); }
.dk-style-chip.selected { border-color: var(--primary); background: var(--primary-light); }
.dk-style-swatch { height: 46px; border-radius: 9px; margin-bottom: 10px; }
.dk-style-chip span { font-size: 13px; font-weight: 700; color: var(--text); }
.dk-style-swatch-minimal { background: linear-gradient(135deg,#F8FAFA,#E5E7EB); }
.dk-style-swatch-luxury { background: linear-gradient(135deg,#1A1A1A,#3A3A3A); }
.dk-style-swatch-bold { background: linear-gradient(135deg,#14B8A6,#0F766E); }
.dk-style-swatch-warm { background: linear-gradient(135deg,#F79009,#F04438); }
.dk-style-swatch-modern { background: linear-gradient(135deg,#7B5CFF,#14B8B8); }
.dk-style-chip-auto { border-color: var(--primary); background: var(--primary-light); }
.dk-style-chip-auto span { color: var(--primary-dark); }
.dk-style-chip-auto::before { content: "✨ מומלץ"; display: block; font-size: 10.5px; font-weight: 800; color: var(--primary-dark); margin-bottom: 6px; }

.dk-multiselect-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
@media (max-width: 560px) { .dk-multiselect-grid { grid-template-columns: repeat(2, 1fr); } }
.dk-ms-chip {
  border: 1.5px solid var(--border); border-radius: 10px; padding: 10px; text-align: center; cursor: pointer;
  background: var(--surface); font-family: inherit; font-size: 13px; font-weight: 600; color: var(--text);
}
.dk-ms-chip.selected { border-color: var(--primary); background: var(--primary-light); color: var(--primary-dark); }

/* Build transition screen */
.dk-transition-wrap { text-align: center; padding: 50px 20px; }
.dk-transition-wrap h2 { font-size: 22px; margin: 0 0 30px; }
.dk-transition-steps { display: grid; gap: 14px; max-width: 360px; margin: 0 auto; text-align: start; }
.dk-transition-step { display: flex; align-items: center; gap: 12px; font-size: 14.5px; color: var(--text-muted); transition: color .2s ease; }
.dk-transition-step.active { color: var(--text); font-weight: 700; }
.dk-transition-step.done { color: var(--success); }
.dk-transition-dot { width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--border); flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 11px; }
.dk-transition-step.active .dk-transition-dot { border-color: var(--primary); }
.dk-transition-step.active .dk-transition-dot::after { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--primary); animation: dkSpin 1s linear infinite; }
.dk-transition-step.done .dk-transition-dot { border-color: var(--success); background: var(--success); color: #fff; }
@keyframes dkSpin { 0% { opacity: .3; } 50% { opacity: 1; } 100% { opacity: .3; } }

/* Generated preview screen */
.dk-genpreview-wrap { max-width: 1040px; margin: 0 auto; padding: 36px 20px 70px; }
.dk-genpreview-head { text-align: center; margin-bottom: 20px; }
.dk-genpreview-head h1 { font-size: 26px; margin: 0 0 8px; }
.dk-genpreview-tags { display: flex; justify-content: center; gap: 8px; flex-wrap: wrap; }
.dk-genpreview-frame-wrap { border: 1px solid var(--border); border-radius: 16px; overflow: hidden; box-shadow: var(--shadow); margin: 22px 0; }
.dk-genpreview-frame-wrap iframe { width: 100%; height: 66vh; min-height: 440px; border: none; display: block; }
.dk-genpreview-actions { display: flex; justify-content: center; gap: 12px; flex-wrap: wrap; }
.dk-genpreview-style-opts { display: flex; justify-content: center; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.dk-genpreview-style-opts button { font-size: 12.5px; }

/* Publish checklist modal */
.dk-checklist { margin: 18px 0 22px; display: grid; gap: 10px; }
.dk-checklist-item { display: flex; align-items: center; gap: 10px; font-size: 14px; color: var(--text); }
.dk-checklist-item .ok { color: var(--success); }
.dk-checklist-item .warn { color: var(--warning); }

/* Collapsible informational asides (host-info-box/go-live-box/purchase
   details inside the Publish modal) — collapsed by default so the
   modal leads with the one actual decision, not a wall of text. */
.dk-details { margin-top: 10px; }
.dk-details summary {
  cursor: pointer; font-size: 12.5px; font-weight: 700; color: var(--primary-dark);
  list-style: none; display: flex; align-items: center; gap: 4px; user-select: none;
}
.dk-details summary::-webkit-details-marker { display: none; }
.dk-details summary::after { content: "▾"; font-size: 10px; transition: transform .15s ease; }
.dk-details[open] summary::after { transform: rotate(180deg); }
.dk-details .host-info-box, .dk-details .go-live-box { margin-top: 8px; }

/* Publish modal: the existing .export-panel (finish-gate/unlock-done —
   real Gumroad/license/watermark logic, untouched) gets reparented in
   here wholesale by js/site-wizard-router.js's dkOpenPublishModal, so
   publishing never yanks the user out of the Builder-Shell into the old
   full-page sidebar. The Shell stays visible, just dimmed, behind it. */
.dk-publish-overlay {
  position: fixed; inset: 0; background: rgba(15,23,42,.5); z-index: 6000;
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.dk-publish-modal {
  background: var(--surface); border-radius: 20px; box-shadow: var(--shadow-lg);
  max-width: 480px; width: 100%; max-height: 88vh; overflow-y: auto; padding: 30px 28px;
  position: relative;
}
.dk-publish-modal .domain-guide-close { position: absolute; top: 16px; inset-inline-start: 16px; background: var(--bg); border: none; width: 32px; height: 32px; border-radius: 50%; font-size: 15px; cursor: pointer; color: var(--text-secondary); }
.dk-publish-modal .domain-guide-close:hover { background: var(--primary-light); color: var(--primary-dark); }
.dk-publish-modal h2 { font-size: 19px; margin: 0 0 16px; color: var(--text); }
.dk-publish-modal .export-panel { margin-top: 0 !important; }

/* Automate teaser */
.dk-automate-wrap { max-width: 720px; margin: 70px auto; text-align: center; padding: 0 20px; }
.dk-automate-wrap h1 { font-size: 32px; margin: 0 0 14px; }
.dk-automate-wrap p { color: var(--text-secondary); font-size: 16px; line-height: 1.7; }
.dk-automate-example { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 18px 20px; margin: 24px 0; font-size: 14.5px; color: var(--text); text-align: start; }
.dk-automate-flow { display: flex; justify-content: center; gap: 10px; flex-wrap: wrap; margin: 26px 0; font-size: 13px; font-weight: 700; color: var(--primary-dark); }
.dk-automate-flow span.sep { color: var(--text-muted); font-weight: 400; }
