/* ============================================================
   THEME - single source of truth for every colour on the site.
   ------------------------------------------------------------
   This is a complete daisyUI theme definition, the same shape daisy's own
   themes.css uses ([data-theme="name"] { --color-*: ... }). Previously this
   block only overrode 2 of daisy's ~20 tokens (primary, accent) and silently
   inherited the rest from daisy's stock "night" theme on the CDN - so nobody
   editing this file could see, or fully control, the theme actually in use.
   Every token below is now defined locally: --color-primary/--color-accent
   are OUR brand values (unchanged from before); everything else is daisy's
   stock "night" theme, copied in as plain hex so this file is authoritative
   and does not silently drift if the CDN's theme ever changes upstream.
   Change a value here and every Tailwind/daisy utility that uses it
   (text-accent, border-primary, bg-neutral, .btn-primary, ...) follows.
   ============================================================ */
[data-theme="night"] {
  color-scheme: dark;

  /* --- brand: RatchTech's own colours --- */
  --color-primary: #70f1f1; /* cyan - primary buttons, active nav, borders */
  --color-accent: #fa85ea; /* pink - "TECH" in the wordmark, headings, the duck mark */

  /* --- surfaces & text (daisy's stock "night" values) --- */
  --color-base-100: #0f172a;
  --color-base-200: #0c1425;
  --color-base-300: #0a1120;
  --color-base-content: #c9cbd0;
  --color-neutral: #1e293b;
  --color-neutral-content: #cdd0d4;

  /* --- text-on-colour pairs (contrast-checked against OUR brand values:
     primary 14.5:1, accent 9.1:1 - both comfortably pass, so daisy's stock
     pairing still works and needed no change) --- */
  --color-primary-content: #010d15;
  --color-accent-content: #14040c;

  /* --- secondary (daisy stock - not currently used by any component on the
     site, kept for completeness/future use) --- */
  --color-secondary: #818cf8;
  --color-secondary-content: #060715;

  /* --- status colours (daisy stock; not currently used, kept for
     completeness so the theme is genuinely complete in one place) --- */
  --color-info: #0ca5e9;
  --color-info-content: #000000;
  --color-success: #2fd4bf;
  --color-success-content: #01100d;
  --color-warning: #f4bf51;
  --color-warning-content: #140d02;
  --color-error: #fb7085;
  --color-error-content: #150406;

  /* --- shape (daisy stock) --- */
  --radius-selector: 1rem;
  --radius-field: 0.5rem;
  --radius-box: 1rem;
  --size-selector: 0.25rem;
  --size-field: 0.25rem;
  --border: 1px;
  --depth: 0;
  --noise: 0;
}

/* Non-daisy surfaces used directly by this site's markup (footer, service
   cards, About panels, the contact form) - kept in the same theme block so
   every colour choice lives in one place, not just daisy's own tokens. */
:root {
  --rt-panel-surface: #14161a; /* dark tile: footer, cards, About panels */
  /* Lightbox sizing is fluid - see #image-modal img. The gap scales with the
     viewport so it is not a chunky border on a phone. */
  --rt-modal-gap: clamp(0.5rem, 1.6vw, 0.875rem);
  --rt-header-surface: #05070cd8; /* header/#background field - same colour,
     84% alpha so page content can show a little through underneath it */
}

/* ------------------------------------------------------------
   Third-party BRAND colours - fixed by the other company's guidelines, not
   part of our theme, and must never be retuned alongside it. Named here so
   every colour used on the site is still visible from a single file.
   ------------------------------------------------------------ */
:root {
  --rt-beckhoff-red: #e2001a;
  --rt-siemens-teal: #009999;
}

/* ------------------------------------------------------------
   NOT reachable from here - flagged so a future theme change doesn't quietly
   miss them. Browsers never apply a page's CSS to a separately-loaded image
   file (favicon, <img src="...svg">), so these bake their colours in at
   generation time and must be regenerated by hand if the theme changes:
     assets/favicon/favicon.svg              #14161a  #fa85ea
     assets/brand/quack_wordmark.svg       #f2f2f0  (off-white, not themed)
     assets/social/rt_linkedin_*.svg     #14161a  #fa85ea
     assets/wallpaper/rt_4k*.svg         #14161a  #fa85ea  #f2f2f0
   ------------------------------------------------------------ */

:root {
  --hero-nav-h: var(--nav-height, 4.5rem); /* measured in scripts.js */
  --hero-breathing: 6rem; /* hero padding + the gap kept at the bottom */
  --hero-max-w: 102rem; /* max width of the hero row */
  --hero-side-pad: clamp(6rem, 4vw, 4rem); /* hero padding, left + right */
  --hero-gap: clamp(0.5rem, 6vw, 11rem); /* gap between graphic and copy */
  --hero-copy-w: 34rem; /* width of the copy column */
  --hero-svg-scale: 0.9; /* graphic size as a share of the height under the nav */
}

#home_hero {
  position: relative;
  /* isolation/overflow-clip previously existed to contain the rotated duck
     watermark, which now lives on #duck-watermark and is fixed to the viewport.
     Nothing in the hero needs clipping any more. */
  margin-top: 0vh;
  align-items: center;
  justify-items: center;
}

#home_hero_content {
  width: 100%;
  max-width: var(--hero-max-w);
  gap: var(--hero-gap);
}

/* Duck watermark, fixed to the viewport so it stays visible the whole way down
   the page instead of scrolling away with the hero.

   It hangs off <body> rather than #home_hero: the hero clips its own overflow,
   which is what confined the old version to the first screen.

   position: fixed takes it out of flow and pins it to the viewport, and a
   NEGATIVE z-index drops it behind page content. That only works because body
   creates no stacking context of its own - so the duck sits beneath the
   surfaces painted by .header_block, #background and the footer.

   Those surfaces are translucent (--rt-header-surface is 84% alpha), which is
   deliberate: the duck reads faintly through them, so the whole page shares one
   continuous backdrop rather than the watermark stopping at the hero's edge. */
/* daisyUI paints background-color on :root, and a background on the ROOT
   element is propagated to the canvas - painted beneath everything. Moving the
   page colour onto <body> instead keeps the watermark layer paintable. */
:root {
  background-color: transparent;
}

body {
  /* The page colour, already composited. This used to be produced by painting
     a translucent --rt-header-surface over base-100 in three places. */
  background-color: #070911;
}

/* Duck watermark.
   ---------------------------------------------------------------
   A real element (#duck-watermark, first child of <body>) rather than a
   pseudo-element, so it can be selected and inspected in DevTools.

   The 30deg tilt is baked into duck_watermark_tilted.svg, so this rule needs no
   rotation at all.

   position: fixed keeps it on screen the whole way down; scripts.js writes
   --duck-drift from the scroll position so it visibly travels while you
   scroll. */
#duck-watermark {
  position: fixed;
  inset: 0;
  z-index: 0;
  transform: translateY(var(--duck-drift, 0px));
  /* promote to its own layer up front, so the SVG is rasterised once at load
     instead of on the first scroll frame - that first-move hitch reads as a jump */
  will-change: transform;
  pointer-events: none;
  background-image: url("../img/duck_watermark_tilted.svg");
  background-repeat: no-repeat;
  background-position: 12% 50%;
  background-size: min(58vw, 950px) auto;
  opacity: 0.07;
}

@media (width < 48rem) {
  #duck-watermark {
    background-size: 92vw auto;
    background-position: 50% 50%;
    opacity: 0.05;
  }
}

/* Reduced motion: no scroll-linked drift. scripts.js checks the same query. */
@media (prefers-reduced-motion: reduce) {
  #duck-watermark {
    transform: none;
  }
}

/* The watermark is a sibling of the page content in the same stacking context,
   so the content is lifted above it explicitly. */
.header_block,
#background,
footer {
  position: relative;
  z-index: 1;
}

#home_hero_copy {
  width: 100%;
  max-width: var(--hero-copy-w);
}

#home_hero_svg {
  flex: 0 0 auto;
  width: auto;
  max-width: 100%;
  height: min(
    calc(
      (100svh - var(--hero-nav-h) - var(--hero-breathing)) *
        var(--hero-svg-scale)
    ),
    calc(
      min(100vw, var(--hero-max-w)) - var(--hero-side-pad) - var(--hero-gap) -
        var(--hero-copy-w)
    )
  );
}

@media (width < 64rem) {
  #home_hero_svg {
    height: max(
      15rem,
      min(
        calc((100svh - 26rem - var(--hero-gap)) * var(--hero-svg-scale)),
        78vw
      )
    );
  }
}

#our_work_section {
  margin-top: 10vh;
  padding-bottom: 14vh;
}
/* Sticky navbar. It is a sibling of .header_block rather than a child, so its
   containing block is <body> and it holds the top of the viewport for the
   whole page - inside the header it would be released as soon as the header
   scrolled past. */
/* Already stacks above the duck watermark via this z-index, so it is
   deliberately left out of the z-index:1 group above - re-declaring
   position here would clash with that rule. */
#site-nav {
  position: sticky;
  top: 0;
  z-index: 50;
}

/* Outside the header it has no background of its own and page content would
   scroll straight through it. The blur sits on the inner bar rather than on
   #site-nav because backdrop-filter would make that the containing block for
   the drawer's position: fixed panel, breaking the mobile menu. */
#site-navbar {
  /* The sticky bar genuinely needs to obscure content scrolling underneath it,
     so unlike the other page surfaces this one keeps a fill. It sits above the
     duck watermark (z-index 50) rather than over it in the same layer, so the
     watermark is unaffected. */
  background-color: #070911e6;
  backdrop-filter: blur(10px);
}

/* Keeps hash links clear of the sticky bar, and keeps scrollIntoView({block:
   "center"}) centring on the visible area rather than the full viewport. */
html {
  scroll-padding-top: var(--hero-nav-h);
}

.header_block {
  background-color: transparent;
  /* the navbar no longer sits inside it, so the hero fills what is left */
  min-height: calc(100svh - var(--hero-nav-h));
}

/* #background sits on <main> and had no rule, so Services and Featured Work
   fell through to base-100 while the hero above them was dark. Same value as
   .header_block, so the dark field runs unbroken from the hero to the footer
   regardless of what shows through the alpha. */
#background {
  background-color: transparent;
}

/* The nav entry for whichever section is currently under the sticky bar. The
   resting state is text-base-content/70, so this needs the #site-nav id to
   outrank that utility on specificity rather than just following it. */
#site-nav a.nav-active {
  color: var(--color-primary);
  opacity: 1;
}

/* One surface for the footer, the About page panels and the service cards.
   The header sits on var(--rt-header-surface); this is that same near-black lifted slightly
   toward grey, so these blocks read as sitting on the page rather than being
   cut out of the same darkness. Paired with border-primary the way the header
   pairs its own background with border-b border-primary. */
.panel-surface {
  background-color: var(--rt-panel-surface);
}

/* Icon-only WhatsApp trigger: no brand-green fill, just the mark rendered in
   the nav's own colours so it sits quietly next to Contact Us rather than
   competing with it. Matches the resting/hover treatment the text nav links
   already use (text-base-content/70 -> full opacity, colour -> accent). */
.btn-whatsapp {
  /* daisy's .btn:hover also redefines --btn-bg/--btn-shadow/--btn-inset (a
     grey hover tint + shadow baked into any ghost button), which showed up
     as a colour flash before the icon settled on pink. Neutralising these
     custom properties too - not just background-color/box-shadow - stops
     that tint from ever being computed, so hover changes only the icon's
     colour. */
  --btn-bg: transparent;
  --btn-border: transparent;
  --btn-shadow: none;
  --btn-inset: none;
  background-color: transparent;
  border-color: transparent;
  box-shadow: none;
  color: var(--color-base-content);
  opacity: 0.7;
}

.btn-whatsapp:hover {
  --btn-bg: transparent;
  --btn-border: transparent;
  --btn-shadow: none;
  --btn-inset: none;
  background-color: transparent;
  border-color: transparent;
  box-shadow: none;
  color: var(--color-accent);
  opacity: 1;
}

/* Skip link - lets keyboard and screen-reader users jump straight past the
   nav to the page content (WCAG 2.4.1 Bypass Blocks). Visually hidden until
   focused, then pinned to the top-left so it is clearly visible. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
}

.skip-link:focus {
  left: 0.5rem;
  top: 0.5rem;
  padding: 0.75rem 1.25rem;
  background-color: var(--color-primary);
  color: var(--color-primary-content);
  border-radius: var(--radius-field);
  font-weight: 600;
}

/* ------------------------------------------------------------
   Featured Work carousel - see the matching block in scripts.js.
   ------------------------------------------------------------ */

/* The outer carousel must move between projects ONLY via its buttons or its
   own timer. overflow:hidden keeps it scrollable programmatically (scrollTo
   still works) while removing it as a user-scrollable surface, so a finger
   swipe cannot jump projects. Snapping is off because the script positions it
   exactly; leaving snap on would fight the programmatic scroll. Note this is
   done with overflow rather than touch-action, because touch-action is
   intersected down the ancestor chain - blocking pan-x here would also kill
   the horizontal swipe on the photo carousels nested inside. */
#work_carousel {
  overflow: hidden;
  scroll-snap-type: none;
}

/* The photo carousels stay natively swipeable. overscroll-behavior-x:contain
   stops a swipe that runs past the last photo from chaining outward into the
   outer carousel and dragging the project along with it. */
[data-image-carousel] {
  overscroll-behavior-x: contain;
}

/* Photo indicator dots, injected by scripts.js only where a segment holds more
   than one photo. The button is a full 24px so it clears the 24x24 minimum
   touch target (WCAG 2.5.8); the visible dot is drawn by ::after, so the dot
   can stay small without shrinking the tap area. */
.carousel-dot {
  width: 1.5rem;
  height: 1.5rem;
  display: grid;
  place-items: center;
  cursor: pointer;
  background: none;
  border: 0;
  padding: 0;
}

.carousel-dot::after {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 9999px;
  background-color: var(--color-base-content);
  opacity: 0.35;
  transition:
    opacity 0.2s,
    background-color 0.2s,
    transform 0.2s;
}

.carousel-dot:hover::after {
  opacity: 0.7;
}

.carousel-dot[aria-current="true"]::after {
  background-color: var(--color-accent);
  opacity: 1;
  transform: scale(1.25);
}

.carousel-dot:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: 9999px;
}

/* ------------------------------------------------------------
   Image lightbox (see the matching block in scripts.js).
   A native <dialog>, so Escape, focus trapping and the inert background come
   from the browser.
   ------------------------------------------------------------ */

/* The gap between the panel edge and the image is a single uniform padding,
   so it is identical on all four sides for every image whatever its aspect or
   native size. That means NO letterbox bars: the panel follows the image
   instead of the image sitting inside a fixed box.

   The images differ a lot natively (961x521, 1361x848, 1920x1080), so the
   image is driven to a common width and only clamped by height - which scales
   the small one UP rather than leaving it at native size. Their footprints
   then land within ~3% of each other while the border stays constant. */
#image-modal {
  /* fit-content, NOT auto: with inset:0 an absolutely positioned element and
     width:auto resolves to "stretch to the containing block", so the dialog
     filled the viewport and the image floated small inside it. fit-content
     shrink-wraps to the content while inset:0 + margin:auto still centres. */
  width: fit-content;
  height: fit-content;
  max-width: 94vw;
  max-height: 92dvh;
  padding: var(--rt-modal-gap);
  overflow: hidden;
  border: 1px solid var(--color-primary);
  border-radius: var(--radius-box);
  background-color: var(--rt-panel-surface);
  color: var(--color-base-content);

  /* A <dialog> is centred by the UA stylesheet's margin:auto, but that is
     fragile once width/height are set. Pin all four insets and centre. */
  inset: 0;
  margin: auto;
}

#image-modal::backdrop {
  background-color: rgb(3 5 9 / 0.8);
}

#image-modal img {
  display: block;
  margin-inline: auto;
  height: auto;

  /* The responsive box lives HERE, in CSS, as real max-* properties:
       - clamp() scales fluidly between a phone and a desktop with no fixed
         breakpoint and no magic pixel width
       - dvh, not vh, so mobile browser chrome collapsing does not push the
         modal off screen
       - rem bounds, so it respects the user's font size
     scripts.js reads these back with getComputedStyle (max-width/max-height
     resolve to px, unlike an unregistered custom property) and fits the
     image's aspect inside them. CSS decides how big; JS only decides the
     shape. */
  /* Subtract the panel's own padding, so image + border can never exceed the
     panel's max-width/max-height. A clamp() with a rem FLOOR would overflow a
     320px phone (the floor can exceed the viewport); min() cannot. */
  max-width: min(62rem, 94vw - 2 * var(--rt-modal-gap));
  max-height: min(
    calc(80dvh - 2 * var(--rt-modal-gap)),
    calc(92dvh - 2 * var(--rt-modal-gap) - 3.5rem)
  );

  border-radius: calc(var(--radius-box) - var(--rt-modal-gap) / 2);
}

/* Short/landscape phones: height is the scarce axis, so give the image more of
   it and let width follow the aspect ratio down. */
@media (orientation: landscape) and (height < 30rem) {
  #image-modal img {
    max-height: calc(80dvh - 2 * var(--rt-modal-gap));
  }
}

#image-modal-caption {
  margin: 0;
  padding: clamp(0.5rem, 1.6vw, 0.75rem) 0.25rem 0;
  font-size: clamp(0.8125rem, 0.75rem + 0.25vw, 0.875rem);
  line-height: 1.4;
  text-align: center;
  text-wrap: balance;
  color: color-mix(in oklab, var(--color-base-content) 75%, transparent);
}

#image-modal-close {
  position: absolute;
  /* offset from the image's corner, not the panel's, so it sits inside the
     picture and the uniform border around it stays clean */
  top: calc(var(--rt-modal-gap) + 0.5rem);
  right: calc(var(--rt-modal-gap) + 0.5rem);
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 0;
  border-radius: 9999px;
  background-color: rgb(7 9 17 / 0.65);
  color: #ffffff;
  cursor: pointer;
}

#image-modal-close:hover {
  background-color: rgb(7 9 17 / 0.85);
  color: var(--color-accent);
}

#image-modal-close:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* ---------- Founder-photo doodle layer ----------------------------------
   Hovering a founder portrait swaps the cursor for a permanent marker and
   lets you scribble on their face. Each stroke is kept as points and fades
   out on its own 60s timeline once it is finished, so an old moustache is
   already going while a fresh pair of glasses is still solid.
   Drawing lives in setupDoodleSurfaces() in scripts.js, which adds
   .doodle-ready only on fine-pointer devices - on touch, a drag has to stay
   a scroll, so the whole feature stays off there.                          */
:root {
  --rt-doodle-ink: #fa85ea;  /* marker colour, matches the cursor's nib */
}

.doodle-surface {
  position: relative;
  display: block;
}

/* the marker cursor only appears once the JS has opted this surface in */
.doodle-surface.doodle-ready {
  cursor: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 32 32%22 width=%2232%22 height=%2232%22%3E %3Cg transform=%22rotate(45 16 16)%22%3E %3Crect x=%2212.5%22 y=%222%22 width=%227%22 height=%2214%22 rx=%221.6%22 fill=%22%231b1e24%22 stroke=%22%23f2f2f0%22 stroke-width=%221.1%22/%3E %3Crect x=%2212.5%22 y=%2215%22 width=%227%22 height=%223.2%22 fill=%22%23f2f2f0%22/%3E %3Cpath d=%22M13.6 18.2 h4.8 l-1.1 5.4 h-2.6 Z%22 fill=%22%23fa85ea%22 stroke=%22%231b1e24%22 stroke-width=%220.8%22 stroke-linejoin=%22round%22/%3E %3Cpath d=%22M14.7 23.6 h2.6 l-1.3 3.4 Z%22 fill=%22%23fa85ea%22/%3E %3C/g%3E %3C/svg%3E") 8 24, crosshair;
}

/* a native image-drag would steal the gesture mid-stroke, and on iOS a long
   press pops the save-image sheet over the top of whatever you are drawing */
.doodle-surface img {
  user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}

/* A press on a photo draws, on any pointer. touch-action: none is what stops
   the browser turning a finger drag into a scroll - it only applies to the
   photos themselves, so the rest of the page scrolls exactly as normal. */
.doodle-surface {
  touch-action: none;
}

/* the wrapper owns the pointer handlers; the canvas is purely a display
   surface, and inherits the photo's corner radius so strokes clip to it */
.doodle-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Confirmation toast, built by scripts.js on share so the markup stays out
   of all four pages. */
#doodle-toast {
  position: fixed;
  left: 50%;
  bottom: 1.5rem;
  z-index: 60;
  transform: translate(-50%, 0.75rem);
  padding: 0.6rem 1.1rem;
  border: 1px solid var(--color-primary);
  border-radius: 9999px;
  background-color: var(--rt-panel-surface);
  color: var(--color-base-content);
  font-size: 0.875rem;
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.45);
  opacity: 0;
  pointer-events: none;
  transition: opacity 220ms ease, transform 220ms ease;
}

#doodle-toast.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
}

@media (prefers-reduced-motion: reduce) {
  #doodle-toast { transition: opacity 220ms ease; transform: translate(-50%, 0); }
}

/* Floating control bar: the touch-only draw toggle plus the share pill. Built
   by scripts.js so the markup stays out of all four pages. Sits above the
   toast so both can be on screen at once. */
#doodle-bar {
  position: fixed;
  left: 50%;
  bottom: 5rem;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  transform: translate(-50%, 0.75rem);
  opacity: 0;
  visibility: hidden;
  transition: opacity 220ms ease, transform 220ms ease, visibility 0s linear 220ms;
}

#doodle-bar.is-visible {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition-delay: 0s;
}

/* share only earns its place once a photo actually has ink on it */
#doodle-share {
  display: none;
}

#doodle-share.is-visible {
  display: inline-flex;
}

.doodle-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 1.15rem;
  border: 1px solid var(--color-primary);
  border-radius: 9999px;
  background-color: var(--rt-panel-surface);
  color: var(--color-base-content);
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.45);
  transition: color 150ms ease, border-color 150ms ease, background-color 150ms ease;
}

/* comfortably past the 44px minimum touch target */
@media (any-pointer: coarse) {
  .doodle-pill {
    padding: 0.85rem 1.3rem;
  }
}

.doodle-pill:hover {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

.doodle-pill:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  #doodle-bar {
    transition: opacity 220ms ease, visibility 0s linear 220ms;
    transform: translate(-50%, 0);
  }
}

/* Per-photo sponge. Sits just above its own portrait and only appears while
   that face actually has something on it, so each founder is cleaned
   independently. Absolutely positioned, so showing and hiding it never
   reflows the card. */
.doodle-sponge {
  position: absolute;
  left: 50%;
  /* --rt-sponge-lift is measured per card in scripts.js */
  bottom: calc(100% + var(--rt-sponge-lift, 0.4rem));
  z-index: 2;
  display: grid;
  place-items: center;
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--color-primary);
  border-radius: 9999px;
  background-color: var(--rt-panel-surface);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, 0.35rem) scale(var(--rt-sponge-scale, 1));
  transform-origin: bottom center;
  box-shadow: 0 6px 18px rgb(0 0 0 / 0.45);
  transition: opacity 200ms ease, transform 200ms ease, border-color 150ms ease,
    visibility 0s linear 200ms;
}

.doodle-sponge.is-visible {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0) scale(var(--rt-sponge-scale, 1));
  transition-delay: 0s;
}

.doodle-sponge:hover {
  border-color: var(--color-accent);
}

.doodle-sponge:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.doodle-sponge img {
  display: block;
  width: 1.75rem;
  height: auto;
  pointer-events: none;
}

/* the sponge is a control, not part of the drawing area */
.doodle-sponge {
  touch-action: auto;
}

@media (prefers-reduced-motion: reduce) {
  .doodle-sponge {
    transition: opacity 200ms ease, visibility 0s linear 200ms;
    transform: translate(-50%, 0) scale(var(--rt-sponge-scale, 1));
  }
}

/* Share menu: opens above the pill; items are plain buttons so keyboard and
   screen-reader users get real controls. Hidden until the pill is pressed. */
.doodle-menu {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 0.5rem);
  transform: translateX(-50%);
  display: none;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 11rem;
  padding: 0.4rem;
  border: 1px solid var(--color-primary);
  border-radius: 1rem;
  background-color: var(--rt-panel-surface);
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.45);
}

.doodle-menu.is-open {
  display: flex;
}

.doodle-menu-item {
  padding: 0.55rem 0.9rem;
  border: 0;
  border-radius: 0.6rem;
  background: transparent;
  color: var(--color-base-content);
  font: inherit;
  font-size: 0.875rem;
  text-align: left;
  cursor: pointer;
}

.doodle-menu-item:hover,
.doodle-menu-item:focus-visible {
  background-color: rgb(255 255 255 / 0.06);
  color: var(--color-accent);
  outline: none;
}

.doodle-menu-item:focus-visible {
  box-shadow: inset 0 0 0 2px var(--color-primary);
}

