/* Component-owned styles (shipped only when this component is used) */
@layer components {

/*
 * SPDX-FileCopyrightText: 2026 The freelance-persona_theme Project Contributors
 *
 * SPDX-License-Identifier: MIT
 */

/*--------------------------------------------------------------
# Hero Section
--------------------------------------------------------------*/
.hero {
  width: 100%;
  min-height: 100vh;
  /* Small-viewport height: on phones 100vh includes the area under the
     browser URL bar, pushing bottom-anchored hero content below the
     fold. svh is always the visible area (identical to vh on desktop). */
  min-height: 100svh;
  position: relative;
  /* Padding removed to ensure full-bleed background without box-model conflicts.
     Config-driven extra padding (old pt-5/pb-5) is injected per-axis. */
  padding: var(--hero-align-pad-top, 0rem) 0 var(--hero-align-pad-bottom, 0rem);
  display: flex;
  /* Default alignment (overridden on mobile); config-driven */
  align-items: var(--hero-align-items, center);
  justify-content: center;
  background-color: var(--background-color); /* Match theme color to hide sub-pixel gaps */
  overflow: hidden;

  /* Hero attribution: positioned bottom-right, above overlay */
  --attribution-font-size: 0.65rem;


  .img-attribution {
    z-index: 5;
    bottom: 1rem;
    right: 2.5rem;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0;

    /* Mobile specific adjustments */
    @media (max-width: 1023px) {
      right: 0.8rem; /* Nudge closer to edge (was 2.5rem) */
      bottom: 0.8rem;
      --attribution-font-size: 0.45rem; /* Smaller text */
    }
  }
}

.hero img {
  position: absolute;

  /* Aggressive fix: Oversize by 2px on all sides to cover any sub-pixel left/bottom gaps */
  top: -2px;
  left: -2px;
  /* max-width must match: wind4's reset caps img at 100%, killing the oversize */
  width: calc(100% + 4px);
  max-width: calc(100% + 4px);
  height: calc(100% + 4px);
  /* Ensure no rounding leaks background */
  border-radius: 0 !important;
  object-fit: cover;
  object-position: var(--desktop-image-anchor, right bottom);
  z-index: 0;

  @media (max-height: 500px) {
    object-position: right center;
  }
}

.hero:before {
  content: "";
  background: color-mix(in srgb, var(--background-color), transparent var(--transparency));
  position: absolute;
  top: -2px;
  left: -2px;
  width: calc(100% + 4px);
  height: calc(100% + 4px);
  /* Ensure overlay also matches */
  border-radius: 0 !important;
  z-index: 2;

  /* Dark Mode: "Hazy" Multi-layer overlay */
  /* Stacks a dark layer over a white layer to lift blacks while keeping it dark. */
  @media (prefers-color-scheme: dark) {
    :root:not(:has(.theme-state-light:checked)) & {
      background:
        linear-gradient(
          color-mix(in srgb, var(--background-color), transparent calc(var(--transparency) + 30%)),
          color-mix(in srgb, var(--background-color), transparent calc(var(--transparency) + 15%))
        ),
        /* Dark Dimmer (Adjust % to change darkness - scales with --transparency) */
        linear-gradient(rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0.15));
      /* White Haze (Bottom) */
    }
  }

  @media (prefers-color-scheme: light) {
    :root:has(.theme-state-dark:checked) & {
      background:
        linear-gradient(
          color-mix(in srgb, var(--background-color), transparent calc(var(--transparency) + 30%)),
          color-mix(in srgb, var(--background-color), transparent calc(var(--transparency) + 15%))
        ),
        /* Dark Dimmer (Adjust % to change darkness - scales with --transparency) */
        linear-gradient(rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0.15));
      /* White Haze (Bottom) */
    }
  }
}

.hero .container {
  position: relative;
  z-index: 3;
}

/* --------------------------------------------------------------
   Semantic content column (design-owned since 3.5).
   Widths reproduce the old col-* geometry exactly: the old row's
   -0.75rem margins cancelled the container's +0.75rem padding and
   the col re-added 0.75rem gutters, netting `container_box * pct`
   outer width. Against the padded container inner width that is:
   `calc(pct% + pct*1.5rem - 1.5rem)` — simplified per step below.
   Horizontal alignment comes from auto-margin utilities in markup
   (xMap.block); mobile always resets to full-width/left (below).
   -------------------------------------------------------------- */
.hero-content {
  width: 100%;
}

@media (min-width: 768px) {
  .hero-width-md-8  { width: calc(66.6667% - 0.5rem); }
  .hero-width-md-10 { width: calc(83.3333% - 0.25rem); }
}

@media (min-width: 992px) {
  .hero-width-lg-6  { width: calc(50% - 0.75rem); }
  .hero-width-lg-9  { width: calc(75% - 0.375rem); }
  .hero-width-lg-11 { width: calc(91.6667% - 0.125rem); }
}

.hero h1 {
  margin: 0;
  margin-block: 0; /* Reset UA stylesheet h1 margin — h1 gets larger margins than h2 by default */
  font-size: var(--title-font-size);
  font-weight: 700;
}

/* Typography for .hero p lives in Hero.astro (scoped, single source —
   README 4-level chain via --typing-font-family-override / --font-mono). */

.hero p span {
  letter-spacing: 0.0625rem; /* 1px */
  color: var(--accent-color);
}

/* Dark Mode: Highlighted Style (User Request) */
/* Mimics "selected text" look: White Text on Brand Blue Background. */
/* - Targeting .typed and .typed-cursor specifically to avoid highlighting the */
/*   layout-locking container (which has a fixed min-width). */
@media (prefers-color-scheme: dark) {

  :root:not(:has(.theme-state-light:checked)) .hero p span.typed,
  :root:not(:has(.theme-state-light:checked)) .hero p span.noscript-text {
    background-color: var(--accent-color);
    color: var(--contrast-color);
    padding: 0 0.1em;
    box-decoration-break: clone;
    font-weight: normal;
    text-shadow: none;
    -webkit-text-stroke: 0;
  }
}

@media (prefers-color-scheme: light) {
  :root:has(.theme-state-dark:checked) .hero p span.typed,
  :root:has(.theme-state-dark:checked) .hero p span.noscript-text {
    background-color: var(--accent-color);
    color: var(--contrast-color);
    padding: 0 0.1em;
    box-decoration-break: clone;
    font-weight: normal;
    text-shadow: none;
    -webkit-text-stroke: 0;
  }
}

/* 1. Default (Light Mode): Standard Line Cursor */
/*    The HTML uses '|', so it renders correctly by default. */
/* 1. Default (Light Mode): Standard Line Cursor */
/*    The HTML uses '|', so it renders correctly by default. */
/* Both explicit OS Light vs Explicit Light Override logic */
@media (prefers-color-scheme: light) {
  :root:not(:has(.theme-state-dark:checked)) {
    .hero p span.typed,
    .hero p span.noscript-text {
      background-color: transparent;
      color: var(--accent-color);
      padding: 0;
    }

    /* Make sure the cursor uses the font color, not the transparent/accent color */
    .typed-cursor {
      color: var(--default-color) !important;
      background-color: transparent !important;
      width: auto;
      font-weight: 300;
      margin-left: 0; /* Reset dark margin */
    }
  }
}

@media (prefers-color-scheme: dark) {
  :root:has(.theme-state-light:checked) {
    .hero p span.typed,
    .hero p span.noscript-text {
      background-color: transparent;
      color: var(--accent-color);
      padding: 0;
    }

    /* Make sure the cursor uses the font color, not the transparent/accent color */
    .typed-cursor {
      color: var(--default-color) !important;
      background-color: transparent !important;
      width: auto;
      font-weight: 300;
      margin-left: 0; /* Reset dark margin */
    }
  }
}

/* 2. Dark Mode: Block Cursor */
/*    We transform the '|' into a block using background color and transparency. */
@media (prefers-color-scheme: dark) {
  :root:not(:has(.theme-state-light:checked)) .typed-cursor {
    color: transparent !important; /* Hide the pipe character */
    background-color: var(--accent-color); /* Show the block (Accent Color) */
    width: 0.6em; /* Block width */
    display: inline-block;
    vertical-align: text-bottom; /* Align with text base */
    margin-left: 2px;
  }
}

@media (prefers-color-scheme: light) {
  :root:has(.theme-state-dark:checked) .typed-cursor {
    color: transparent !important; /* Hide the pipe character */
    background-color: var(--accent-color); /* Show the block (Accent Color) */
    width: 0.6em; /* Block width */
    display: inline-block;
    vertical-align: text-bottom; /* Align with text base */
    margin-left: 2px;
  }
}

.hero .social-links {
  /* Consumed from the hero content element's inline style (hero.md frontmatter: */
  /* gap_typing_to_socials). Owns desktop spacing; the mobile block below overrides. */
  margin-top: var(--gap-typing-to-socials, 1.5625rem); /* default 25px */
  gap: 1.5rem;
}

.hero .social-links a {
  font-size: 1.25rem; /* 20px */
  display: inline-block;
  color: color-mix(in srgb, var(--default-color), transparent 30%);
  line-height: 1;
  margin-right: 0rem; /* 20px */
  margin-left: 0rem; /* 20px */
  transition: 0.3s;
}

.hero .social-links a:hover {
  color: var(--accent-color);
}

@media (max-width: 1023px) {
  .hero {
    /* CONTROL TEXT POSITION VERTICALLY */
    align-items: var(--mobile-align-items, flex-end) !important;

    /* Padding-bottom pushes it UP from the bottom edge. */
    /* 0rem = Touching bottom edge. 5rem = High up. */
    /* Negative values are invalid in CSS. */
    padding-bottom: var(--mobile-padding-bottom, 0rem);
  }

  .hero img {
    /* CONTROL LANCY POSITION HERE */
    /* Horizontal (0% Left, 50% Center, 100% Right) */
    object-position: var(--mobile-image-object-position, 84% 0);
  }

  /* --- CONTROL FONT SIZES HERE --- */

  /* TITLE SIZE ("Freelance - Persona") */
  .hero h1 {
    font-size: calc(var(--title-font-size) / 2.5) !important;
  }

  /* TYPING TEXT SIZE ("portfolio |") */
  .hero p,
  .hero p .typing-lock {
    font-size: calc(var(--title-font-size) / 3.5) !important;
    max-width: 95vw;
    overflow: visible;
    white-space: normal !important;
    /* Allow wrapping */
    height: auto !important;
    text-align: var(--mobile-text-align, left) !important;
    justify-content: var(--mobile-justify-content, flex-start) !important;
  }

  /* Content Wrapper: Default width (No Wrapping constraint) */
  .hero .container .hero-content {
    max-width: 100%;
    text-align: var(--mobile-text-align, left) !important;
    /* !important: must beat unlayered mx-auto/ml-auto alignment utilities */
    margin-left: 0 !important;
    margin-right: auto !important;
  }

  /* Override Flex Alignments for Mobile */
  .hero .typing-wrapper,
  .hero .social-links {
    justify-content: var(--mobile-justify-content, flex-start) !important;
  }

  .hero .social-links {
    margin-top: 1rem;
    gap: 1rem;
  }

  .hero .social-links a {
    font-size: calc(var(--title-font-size) / 4) !important;
  }
}
}@layer components {
  .typing-wrapper[data-astro-cid-fuejjq62] {
    display: flex;
    width: 100%;
  }

  .hero[data-astro-cid-fuejjq62] h1[data-astro-cid-fuejjq62] {
    font-family: var(--title-font-family-override, var(--font-heading, sans-serif));
  }

  .hero[data-astro-cid-fuejjq62] p[data-astro-cid-fuejjq62] {
    font-family: var(--typing-font-family-override, var(--font-mono));
    font-size: var(--hero-typing-font-size, 1.625rem);
    margin-top: var(--gap-title-to-typing, .3125rem);
    margin-bottom: 0;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
  }

  .hero[data-astro-cid-fuejjq62] p[data-astro-cid-fuejjq62] span[data-astro-cid-fuejjq62].greeting {
    font-weight: 400;
    margin-right: .3em;
    color: inherit !important;
  }

  .typing-lock[data-astro-cid-fuejjq62] {
    display: inline-block;
    text-align: left;
    white-space: nowrap;
  }

  .typed-cursor[data-astro-cid-fuejjq62] {
    opacity: 1;
    font-weight: 100;
    color: inherit;
    margin-left: 2px;
    display: inline-block;
  }

  .typed-cursor[data-astro-cid-fuejjq62].blinking {
    animation: .7s infinite blink;
  }

  @keyframes blink {
    0% {
      opacity: 1;
    }

    50% {
      opacity: 0;
    }

    100% {
      opacity: 1;
    }
  }

  noscript[data-astro-cid-fuejjq62] {
    display: inline;
  }

  .no-js .typing-lock[data-astro-cid-fuejjq62] {
    display: none !important;
  }

  .no-js .hero[data-astro-cid-fuejjq62] p[data-astro-cid-fuejjq62] {
    white-space: normal !important;
    display: block !important;
  }

  .social-links[data-astro-cid-fuejjq62] {
    display: flex;
  }

  .social-links[data-astro-cid-fuejjq62] a[data-astro-cid-fuejjq62] {
    font-size: 1.25rem;
    color: color-mix(in srgb, var(--default-color), transparent 30%);
    transition: all .3s;
    line-height: 1;
  }

  .social-links[data-astro-cid-fuejjq62] a[data-astro-cid-fuejjq62]:hover {
    color: var(--accent-color);
  }
}
@layer components {
  .plain[data-astro-cid-gvbyacfl].section {
    transform: translate(var(--nudge-x, 0), var(--nudge-y, 0))
      scale(var(--content-scale, 1));
  }
}
@layer components {
  .obfuscated-email-wrapper[data-astro-cid-jwnbsidk] {
    display: inline-block;
    cursor: pointer;
  }

  .email-copy-btn[data-astro-cid-jwnbsidk] {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    color: var(--accent-color);
    font-family: var(--font-mono, monospace);
    font-size: .9em;
    cursor: pointer;
    transition: color var(--transition-hover-time),
      text-decoration-color var(--transition-hover-time);
  }

  .email-copy-btn[data-astro-cid-jwnbsidk] {
    text-decoration: underline;
    text-decoration-color: var(--underline-color);
    text-underline-offset: 3px;
  }

  .contact .info-item:hover .email-copy-btn[data-astro-cid-jwnbsidk], .obfuscated-email-wrapper[data-astro-cid-jwnbsidk]:hover .email-copy-btn[data-astro-cid-jwnbsidk], .email-copy-btn[data-astro-cid-jwnbsidk]:focus-visible {
    color: var(--heading-color);
    font-weight: 600;
    text-decoration-color: var(--accent-color);
  }

  .email-copy-btn[data-astro-cid-jwnbsidk].copied {
    color: var(--accent-color);
  }

  .copy-icon-wrapper[data-astro-cid-jwnbsidk] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    opacity: .7;
    transition: opacity .2s;
  }

  .obfuscated-email-wrapper[data-astro-cid-jwnbsidk]:hover .copy-icon-wrapper[data-astro-cid-jwnbsidk] {
    opacity: 1;
  }

  noscript[data-astro-cid-jwnbsidk] .email-text[data-astro-cid-jwnbsidk] {
    font-family: var(--font-mono, monospace);
    font-size: .9em;
    color: var(--accent-color);
  }
}
/* Component-owned styles (shipped only when this component is used) */
@layer components {

/*
 * SPDX-FileCopyrightText: 2026 The freelance-persona_theme Project Contributors
 *
 * SPDX-License-Identifier: MIT
 */

/* Pre-migration origin: contact.scss (converted in phase 3.1) */

/*--------------------------------------------------------------
# Contact Section
--------------------------------------------------------------*/
.contact .info-item+.info-item {
  margin-top: 2.5rem;
  /* 40px */
}

/* Below the 3-col grid (tablets included): the info rows live in ONE
   box, styled like the About qualifications-box template (bg, hairline
   border, radius). The desktop keeps the bare pills layout. */
@media (max-width: 1023px) {
  .contact .info-list {
    background-color: color-mix(in srgb, var(--default-color), transparent 98%);
    border: 1px solid color-mix(in srgb, var(--default-color), transparent 90%);
    border-radius: 0.3125rem;
    padding: 1.5rem;
  }

  .contact .info-item+.info-item {
    margin-top: 1.25rem;
  }
}

.contact .info-item .contact-icon-pill {
  color: var(--accent-color);
  transition:
    background-color var(--transition-hover-time),
    color var(--transition-hover-time);
  background: color-mix(in srgb, var(--accent-color), transparent 92%);
  width: 2.75rem;
  /* 44px */
  height: 2.75rem;
  /* 44px */
  flex-shrink: 0;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  border-radius: 3.125rem;
  /* 50px */
  margin-right: 0.9375rem;
  /* 15px */

  /* Dark Mode: Increase visibility by mixing with semi-transparent white */
  @media (prefers-color-scheme: dark) {
    :root:not(:has(.theme-state-light:checked)) & {
      background: color-mix(in srgb, var(--accent-color), rgba(255, 255, 255, 0.05) 85%);
    }
  }

  @media (prefers-color-scheme: light) {
    :root:has(.theme-state-dark:checked) & {
      background: color-mix(in srgb, var(--accent-color), rgba(255, 255, 255, 0.05) 85%);
    }
  }
}

.contact .info-item .contact-icon-pill [data-icon] {
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
}

.contact .info-item h3 {
  padding: 0;
  font-size: 1.125rem;
  /* 18px */
  font-weight: 700;
  margin-bottom: 0.3125rem;
  /* 5px */
}

.contact .info-item p {
  padding: 0;
  margin-bottom: 0;
  font-size: 0.875rem;
  /* 14px */
}

.contact .info-item:hover .contact-icon-pill {
  background: var(--accent-color);
  color: var(--contrast-color);
}

/* FIX: Ensure hover state wins over Dark Mode base styles by matching specificity */
@media (prefers-color-scheme: dark) {
  :root:not(:has(.theme-state-light:checked)) .contact .info-item:hover .contact-icon-pill {
    background: var(--accent-color);
    color: var(--contrast-color);
  }
}

@media (prefers-color-scheme: light) {
  :root:has(.theme-state-dark:checked) .contact .info-item:hover .contact-icon-pill {
    background: var(--accent-color);
    color: var(--contrast-color);
  }
}

.contact .contact-form {
  height: 100%;
}

.contact .contact-form .error-message {
  display: none;
  background: #df1529;
  color: #ffffff;
  text-align: left;
  padding: 0.9375rem;
  /* 15px */
  margin-bottom: 1.5rem;
  /* 24px */
  font-weight: 600;
  border-radius: 0.25rem;
  /* 4px */
}

.contact .contact-form .sent-message {
  display: none;
  color: #ffffff;
  background: #059652;
  text-align: center;
  padding: 0.9375rem;
  /* 15px */
  margin-bottom: 1.5rem;
  /* 24px */
  font-weight: 600;
  border-radius: 0.25rem;
  /* 4px */
}

.contact .contact-form .loading {
  display: none;
  background: var(--background-color);
  text-align: center;
  padding: 0.9375rem;
  /* 15px */
  margin-bottom: 1.5rem;
  /* 24px */
}

.contact .contact-form .loading:before {
  content: "";
  display: inline-block;
  border-radius: 50%;
  width: 1.5rem;
  /* 24px */
  height: 1.5rem;
  /* 24px */
  margin: 0 0.625rem -0.375rem 0;
  /* 0 10px -6px 0 */
  border: 0.1875rem solid var(--accent-color);
  /* 3px */
  border-top-color: var(--background-color);
  animation: animate-loading 1s linear infinite;
}

.contact .contact-form fieldset {
  margin-bottom: 1.5rem;
  /* 24px */
}

.contact .contact-form .input-box {
  position: relative;
}

.contact .contact-form .input-box input,
.contact .contact-form .input-box textarea {
  font-size: 0.875rem;
  /* 14px */
  outline: none;
  padding: 0.9375rem 0.9375rem 0.625rem 0.9375rem;
  /* 15px 15px 10px 15px */
  display: block;
  width: 100%;
  border-radius: 0.25rem;
  /* 4px */
  border: 1px solid color-mix(in srgb, var(--default-color), transparent 80%);
  /* Solid background — prevents Chromium compositor flash on focus (alpha change = layer repaint) */
  background: var(--surface-color);
  color: var(--default-color);
  transition: border-color 0.3s ease;
}

.contact .contact-form .input-box textarea {
  resize: vertical;
  min-height: 5rem;
  /* 80px */
}

.contact .contact-form .input-box input:focus,
.contact .contact-form .input-box input:valid,
.contact .contact-form .input-box textarea:focus,
.contact .contact-form .input-box textarea:valid {
  border-color: var(--accent-color);
  /* Same background — no alpha change means no compositor flash */
  background: var(--surface-color);
}

.contact .contact-form .input-box .label {
  color: color-mix(in srgb, var(--default-color), transparent 30%);
  font-size: 0.875rem;
  /* 14px */
  font-weight: normal;
  position: absolute;
  pointer-events: none;
  left: 0.9375rem;
  /* 15px */
  /* Adjusted to match input padding */
  top: 0.9375rem;
  /* 15px */
  transition: all 0.3s ease;

  /* FIXED: Transparent by default so it blends into the input */
  background: transparent;
  padding: 0 0.25rem;
  /* 0 4px */
}

/* --- Active / Floating State --- */
.contact .contact-form .input-box input:focus~.label,
.contact .contact-form .input-box input:valid~.label,
.contact .contact-form .input-box textarea:focus~.label,
.contact .contact-form .input-box textarea:valid~.label {
  transform: translateY(-1.5rem) translateX(-0.3125rem) scale(0.9);
  /* -24px -5px */

  /* FIXED: Become solid only when floating on the border */
  background: var(--background-color);
  color: var(--accent-color);
  z-index: 10;
}

.contact .contact-form .input-box input:user-invalid~.label {
  transform: translateY(-1.5rem) translateX(-0.3125rem) scale(0.9);
  /* -24px -5px */
  background: var(--background-color);
  color: #df1529;
  /* Red label if invalid */
}

@keyframes animate-loading {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

/* Show messaging elements */
.contact .contact-form .loading.show,
.contact .contact-form .error-message.show,
.contact .contact-form .sent-message.show {
  display: block;
}

/* ====================================================
   === MOBILE DENSITY (phones only, <768px) ===
   Goal: the whole section (title, pills, form, button)
   fits one viewport. Pills go 2+2 (grid via utilities in
   the component markup), harvested margins, compact
   inputs. The checkbox label uses an inline font-size, so
   !important is required to shrink it.
   ==================================================== */
@media (max-width: 767px) {
  .contact .info-item .contact-icon-pill {
    width: 2.25rem;
    height: 2.25rem;
    margin-right: 0.625rem;
  }

  .contact .info-item .contact-icon-pill [data-icon] {
    width: 1rem;
    height: 1rem;
  }

  .contact .info-item h3 {
    font-size: 1rem;
    margin-bottom: 0.125rem;
  }

  .contact .info-item p {
    font-size: 0.8rem;
  }

  /* Grid items must be allowed to shrink below content width, else long
     emails force their column wide and blow up the page layout viewport. */
  .contact .info-list {
    align-items: start;
  }

  /* The stacked-layout sibling margin pushes every non-first tile down
     inside its grid cell (40px skew) — the grid gap handles spacing. */
  .contact .info-item + .info-item {
    margin-top: 0;
  }

  .contact .info-item {
    min-width: 0;
  }

  /* The obfuscated-email component's own `display: inline-block` outranks
     the `flex` utility (scoped selector specificity) and would misalign
     this tile against its neighbours — reassert the flex row layout. */
  .contact .info-item.email-wrapper {
    display: flex;
  }

  .contact .info-item > div {
    min-width: 0;
  }

  .contact .obfuscated-email-wrapper {
    max-width: 100%;
  }

  .contact .email-copy-btn,
  .contact noscript .email-text {
    white-space: normal;
    overflow-wrap: anywhere;
  }

  .contact .contact-form fieldset {
    margin-bottom: 0;
  }

  .contact .contact-form .input-box input,
  .contact .contact-form .input-box textarea {
    padding: 0.75rem 0.75rem 0.5rem 0.75rem;
  }

  .contact .contact-form .input-box .label {
    left: 0.75rem;
    top: 0.75rem;
  }

  .contact .contact-form .input-box textarea {
    min-height: 4.5rem;
    height: 5.5rem;
  }

  .contact .checkbox-label {
    font-size: 0.75rem !important;
    line-height: 1.3 !important;
  }
}
}@layer components {
  .contact[data-astro-cid-ajziholi].section {
    transform: translate(var(--nudge-x, 0), var(--nudge-y, 0))
      scale(var(--content-scale, 1));
  }

  .email-wrapper[data-astro-cid-ajziholi] {
    text-decoration: none;
    color: inherit;
    transition: all .3s;
    cursor: pointer;
  }

  .email-wrapper[data-astro-cid-ajziholi]:hover .contact-icon-pill[data-astro-cid-ajziholi] {
    background: var(--accent-color);
    color: var(--contrast-color);
  }

  .email-wrapper[data-astro-cid-ajziholi]:hover .email-copy-btn {
    color: color-mix(in srgb, var(--accent-color), transparent 25%);
  }

  .email-wrapper[data-astro-cid-ajziholi]:hover .copy-icon-wrapper {
    opacity: 1;
  }

  .checkbox-label[data-astro-cid-ajziholi] {
    color: var(--text-muted);
    cursor: pointer;
    user-select: text;
    -webkit-user-select: text;
    -moz-user-select: text;
    caret-color: #0000 !important;
  }

  .check-group[data-astro-cid-ajziholi] {
    min-height: 1.5rem;
    margin-bottom: .125rem;
    padding-left: 1.5em;
  }

  .check-input[data-astro-cid-ajziholi] {
    appearance: none;
    float: left;
    width: 1em;
    height: 1em;
    margin-left: -1.5em;
    vertical-align: top;
    flex-shrink: 0;
    background-color: var(--surface-color);
    border: 1px solid color-mix(in srgb, var(--default-color), transparent 60%);
    border-radius: .25em;
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;
    caret-color: #0000 !important;
  }

  .check-input[data-astro-cid-ajziholi]:checked {
    background-color: var(--accent-color);
    border-color: var(--accent-color);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
  }

  .check-input[data-astro-cid-ajziholi]:active {
    filter: brightness(90%);
  }

  .check-input[data-astro-cid-ajziholi]:focus {
    outline: 0;
    border-color: var(--accent-color);
    box-shadow: 0 0 0 .25rem color-mix(in srgb, var(--accent-color), transparent 75%);
  }
}
/* Component-owned styles (shipped only when this component is used) */

@layer components {

/*
 * SPDX-FileCopyrightText: 2026 The freelance-persona_theme Project Contributors
 *
 * SPDX-License-Identifier: MIT
 */

/* Pre-migration origin: features.scss (converted in phase 3.1) */

/* ====================================================
   === FREELANCE FEATURE GRID ===
   ==================================================== */

.features-section-wrapper {
    position: relative;
    /* Reduced top padding to decrease gap above the grid */
    padding-top: 2rem;
    padding-bottom: 2rem;

    /* === TUNABLE DIALS (readability floors) ===
       0rem = pure cqi (cards follow the master design proportionally
       at every width — identical positions/line breaks, see the
       true-linear root dial). Raising a floor makes text readable on
       small cards but breaks proportionality: floored text eventually
       no longer fits the fixed master shape (403/339) — that is how
       the old 403/540 phone slabs happened. Tune with the shape in
       mind. */
    --feature-title-floor: 0.73rem;
    --feature-desc-floor: 0.55rem;
    --feature-subtitle-floor: 0.625rem;
    --feature-badge-floor: 0.5rem;
}

@media (min-width: 768px) {
    .features-section-wrapper {
        padding-top: 4rem;
        padding-bottom: 4rem;
    }
}

.features-container {
    padding-left: 1.5rem;
    padding-right: 1.5rem;
    position: relative;
    z-index: 10;
}





/* --- Grid Layout --- */
.features-grid {
    display: grid;
    grid-template-columns: 1fr;
    /* 1 column on mobile */
    gap: 2rem;
}

@media (min-width: 640px) {
    .features-grid {
        grid-template-columns: repeat(2, 1fr);
        /* 2 columns on small screens+ */
    }
}

@media (min-width: 1024px) {
    .features-grid {
        grid-template-columns: repeat(3, 1fr);
        /* 3 columns on large screens+ */
    }
}

/* --- Hybrid Card and Link Styling --- */

/* Ensures the entire grid cell is clickable and text styles are maintained */
.feature-card-link {
    text-decoration: none;
    color: inherit;
    display: block;
    height: 100%;

    &:hover, &:focus {
        text-decoration: none;
    }
}

/* Card Container Styling */
/* .feature-card extends .card-base implicitly by usage in component.
   Proportional card (constitution): fixed master shape 403×339,
   internals in cqi — measured at 1920×1080 (card 402.7px):
   pad 32→7.95, radius 12→2.98, icon 64→15.89 (r 8→1.99),
   icon-gap 24→5.96, title 24→5.96 (mb 16→3.97), desc 16→3.97,
   badge font 14.4→3.58 (pads 8/16→1.99/3.97, btl-radius 8→1.99).
   The full 3-line description fits the master shape — no clamp. */
.card-base.feature-card {
    aspect-ratio: 403 / 339;
    padding: 7.95cqi;
    border-radius: 2.98cqi; /* 12px at master — compound beats the
                               fixed 0.75rem on .card-base */
    /* The base structure is handled by _cards.css */
}

/* The Card component wraps children in .card-content (24px at the
   master viewport) — expressed proportionally so the total offset
   (32+24 = 56px @1920) scales with the card. min-height: 0 lets the
   flex item shrink to the fixed-ratio card height. */
.features-grid .card-content {
    padding: 5.96cqi;
    min-height: 0;
}

/* Hover effect for the card container — gated on hover-capable
   pointers (best practice): on touch-only devices :hover triggers on
   tap and STICKS (lift/shadow/desc-color would stay applied). All
   :hover styling lives here; the touch fallback is the
   @media (hover: none) badge rule below. */
@media (hover: hover) {
    /* We target the .card-base inside the wrapper for the lift effect */
    .feature-group-wrapper:hover .card-base {
        transform: translateY(-0.3125rem);
        box-shadow: 0 0.625rem 1.25rem rgba(0, 0, 0, 0.1);
    }

    .feature-group-wrapper:hover .feature-description-card {
        color: var(--accent-color);
    }
}

/* --- Icon and Text Styles (proportional, see feature-card) --- */
.feature-icon-wrapper-outer {
    display: flex;
    margin-bottom: 5.96cqi;
}

.feature-icon-bg {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 15.89cqi;
    height: 15.89cqi;
    border-radius: 1.99cqi;
    background-color: var(--accent-color);
    color: var(--contrast-color);
}

.feature-icon {
    font-size: 5.96cqi; /* Icon <i> elements size from font-size, not width/height */
    color: inherit;

    /* Sizing for Lance Icon specifically (SVG needs explicit dimensions) */
    &.lance-icon-svg {
        width: 8.74cqi;
        height: 8.74cqi;
        fill: currentColor;

        /* Invert the colored part to white when inside the primary background */
        .colored-part {
            fill: var(--contrast-color, #ffffff) !important;
        }
    }
}

.feature-title-card {
    font-size: clamp(var(--feature-title-floor), 5.96cqi, 1.5rem);
    line-height: 1.2;
    font-weight: bold;
    margin-bottom: 3.97cqi;
    white-space: pre-line;
    font-family: var(--font-heading, sans-serif);
}

/* With a subtitle, pull the header together: the tight title→subtitle
   gap is what makes them read as one unit, while the normal rhythm
   returns before the description. */
.feature-title-card:has(+ .feature-subtitle-card) {
    margin-bottom: 1.98cqi;
}

/* Optional sub-heading (content key: subtitle) — a miniature echo of
   the section header (title → accent divider → mono accent subtitle,
   see .section-title em): mono family + accent color tie it to the
   title, the small ::before tick is the divider. ~18px @master;
   proportional via cqi; eats description lines on small cards. */
.feature-subtitle-card {
    font-family: var(--font-mono, monospace);
    font-size: clamp(var(--feature-subtitle-floor), 4.47cqi, 1.125rem);
    line-height: 1.4;
    white-space: pre-line;
    color: var(--accent-color);
    margin-bottom: 3.97cqi;
}

.feature-subtitle-card::before {
    content: "";
    display: block;
    width: 2.5em;
    height: 2px;
    background: var(--accent-color);
    margin-bottom: 0.6em;
}

.feature-description-card {
    font-size: clamp(var(--feature-desc-floor), 3.97cqi, 1rem);
    line-height: 1.625;
    white-space: pre-line;
    font-family: var(--font-body, sans-serif);
    transition: color 0.3s ease-out;
    will-change: color;
}

/* --- Hover Action Element (Call-to-Action Text) --- */
.feature-hover-action {
    position: absolute;
    bottom: 0;
    right: 0;

    padding: 1.99cqi 3.97cqi;
    border-top-left-radius: 1.99cqi;
    font-weight: bold;
    font-size: clamp(var(--feature-badge-floor), 3.58cqi, 0.9rem);
    background-color: var(--accent-color);
    color: var(--contrast-color, #fff);
    z-index: 5;

    /* Hides the element below the card initially */
    transform: translateY(100%);
    transition: transform 0.3s ease-in-out;
    font-family: var(--font-nav, sans-serif);

    /* Fix Chrome rendering artifact */
    backface-visibility: hidden;
    will-change: transform;
}

/* Unavailable State */
.feature-card.unavailable {
    opacity: 0.7;
    /* Exception: needs to affect entire element including images with grayscale */
    filter: grayscale(100%);
    cursor: not-allowed !important;
}

/* Custom style for the unavailable badge */
.feature-card.unavailable .feature-hover-action {
    background-color: var(--text-muted);
    color: white;
    cursor: not-allowed;
}

/* Slides the element up when the user hovers over the card group */
@media (hover: hover) {
    .feature-group-wrapper:hover .feature-hover-action {
        transform: translateY(0);
    }

    /* Optional: reduce hover lift for unavailable cards to feel 'heavier' */
    .card-wrapper:hover .feature-card.unavailable {
        transform: translateY(-2px);
        /* Reduced lift */
    }
}

/* Touch Device Optimization: Always show badge (and no slide/hover
   behavior — touch-only setups get a static, predictable card) */
@media (hover: none) {
    .feature-hover-action {
        transform: translateY(0);
    }
}

/* ====================================================
   === MOBILE LAYOUT (phones only, <768px) ===
   2-column grid, whole grid scales as ONE unit and never
   grows past phone width (the grid centers on wider
   screens). Card internals are fully proportional via the
   unified cqi rules above — no per-breakpoint variants.
   ==================================================== */
@media (max-width: 767px) {
    .features-grid {
        /* Full outer-edge width (same margins as every other
           section) — no centered cap. */
        container-type: inline-size;
        grid-template-columns: repeat(2, 1fr);
        gap: clamp(0.5rem, 2.2cqi, 1rem);
    }

    /* Block flow on phones so the icon can float: in flex-column
       flow floats are ignored, and we want the title text to wrap
       beside the icon. Stacking order is unchanged. */
    .features-grid .card-content {
        display: block;
    }

    /* Icon floats to the card's right edge — the title (and any
       description lines that reach it) wrap beside it, so the
       title "hops up" instead of sitting below the icon row. */
    .feature-icon-wrapper-outer {
        float: right;
        margin-left: 5.96cqi;
        margin-bottom: 0;
    }
}
}@layer components {
  .features-section-wrapper[data-astro-cid-qaofwcrs] {
    transform: translate(var(--nudge-x, 0), var(--nudge-y, 0))
      scale(var(--content-scale, 1));
  }

  .feature-icon-bg[data-astro-cid-qaofwcrs] {
    position: relative;
    display: inline-flex;
    justify-content: center;
    align-items: center;
  }

  .feature-icon[data-astro-cid-qaofwcrs] {
  }

  .feature-icon[data-astro-cid-qaofwcrs].icon-secondary {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    opacity: 0;
  }

  .feature-icon-bg[data-astro-cid-qaofwcrs].has-secondary-icon {
    gap: .25rem;
  }

  .feature-icon-bg[data-astro-cid-qaofwcrs].has-secondary-icon .icon-main[data-astro-cid-qaofwcrs] {
    transform: none;
  }

  .feature-icon-bg[data-astro-cid-qaofwcrs].has-secondary-icon .icon-secondary[data-astro-cid-qaofwcrs] {
    position: static;
    transform: none;
    opacity: 1;
  }
}
/* Component-owned styles (shipped only when this component is used) */

@layer components {

/*
 * SPDX-FileCopyrightText: 2026 The freelance-persona_theme Project Contributors
 * SPDX-FileCopyrightText: 2026, 2026 The freelance-persona_theme Project Contributors
 *
 * SPDX-License-Identifier: MIT
 */

/* Blog Categories Section */

.blog-categories-section {
  --grid-gap: 2rem;
  --mini-group-gap: 5rem;
  /* Gap between standard cards and mini cards */
  --mini-card-padding-y: 3.12cqi;
  /* Proportional (0.8rem at the 410.7px master card) */

  /* === TUNABLE DIALS (readability floors) ===
     The clamps keep the proportional cqi sizing wherever it is >= the
     floor (cards ~300px and up) and only catch narrow 2-col phone
     cards. --blog-phone-ratio: the fixed shape below 640px — taller
     than the master so the floored text + latest-posts fit
     (documented per-override ratio, constitution §3). */
  --blog-desc-floor: 0.63rem;
  --blog-tag-floor: 0.55rem;
  --latest-link-floor: 0.56rem;
  --mini-title-floor: 0.8125rem;
  /* Var-to-var aliases: valid syntax = var(--other-dial) — the
     parenthesized bare form (--blog-desc-floor) is an invalid value. */
  --mini-desc-floor: var(--blog-desc-floor);
  --mini-tag-floor: var(--blog-tag-floor);
  --blog-phone-ratio: 403 / 650;
  /* WHERE IS THE DATE?? → the recent-post list dates are wired below:
     .post-date uses var(--latest-link-floor) as its clamp floor. */
  /* Narrow phones (2-col <480px): the latest-posts list with wrapping
     titles needs more height than the 650 shape holds. */
  --blog-narrow-ratio: 403 / 800;

  transform: translate(var(--nudge-x, 0), var(--nudge-y, 0)) scale(var(--content-scale, 1));
}

.blog-categories-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--grid-gap);

  @media (min-width: 640px) {
    grid-template-columns: repeat(2, 1fr);
  }

  @media (min-width: 1024px) {
    grid-template-columns: repeat(3, 1fr);
  }
}


/* Big category card: fixed master shape 403×534, internals in cqi
   (constitution; measured @1920×1080, card 410.7px). */
.category-card-wrapper .card-base {
  aspect-ratio: 403 / 534;
  border-radius: 2.92cqi;
}

.category-card-wrapper .card-content {
  padding: 5.84cqi; /* 1.5rem at master */
}

.category-image-container {
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: var(--border-radius) var(--border-radius) 0 0;
  /* The fixed-ratio card must never squish the image window to make
     room for overflowing text — text leaks get fixed instead. */
  flex-shrink: 0;
  margin-bottom: 3.9cqi; /* 1rem at the 410.7px master card */
  background: transparent;
  /* Placeholder removed to fix white line artifact */
  position: relative;
  /* Context for overlay */

  /* Attribution: smaller size for cards */
  --attribution-font-size: max(2.34cqi, var(--attribution-min-size)); /* 0.6rem at master */

  /* Mobile specific overrides */
  @media (max-width: 767px) {
    .img-attribution {
      --attribution-font-size: max(1.75cqi, var(--attribution-min-size)); /* 0.45rem */
      bottom: 0.78cqi; /* 0.2rem */
      right: 1.56cqi; /* 0.4rem */
    }
  }
}

.category-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s ease;
  will-change: transform;
  /* Hint for smoother animation */
  backface-visibility: hidden;
  /* Fix flickering */
}

/* Force override any global card hover effects on the image */
.card-wrapper:hover .category-image {
  transform: none !important;
}

.overlay-title-wrapper {
  position: absolute;
  top: 50%;
  width: 100%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--overlay-bg, color-mix(in srgb, black, transparent 60%));
  text-align: center;
  padding-block: 2.92cqi; /* 0.75rem at master */
  transition: background 0.3s ease;
  z-index: 2;
  /* Ensure it stays on top */
  pointer-events: none;
}

.card-wrapper:hover .overlay-title-wrapper,
.category-card-wrapper:hover .overlay-title-wrapper {
  background: var(--overlay-bg, color-mix(in srgb, black, transparent 76%));
}

.overlay-title-text {
  color: var(--overlay-title-color, white) !important;
  font-size: 10.52cqi; /* 43.2/410.7 */
  /* Increased size to match placeholder aesthetic */
  padding-inline: 2.43cqi; /* 1rem at master */
  /* Prevent edge touching */
  font-weight: 700;
  text-shadow: 0 4px 8px rgba(0, 0, 0, 0.158);

  /* Reset Margins for Ribbon Centering */
  margin: 0;
  line-height: 1;
  /* Clamp line height for visual centering */

  /* Smoother Animation */
  transition: transform 0.3s ease-out;
  will-change: transform;
  backface-visibility: hidden;
  transform: scale(1) translateZ(0);
  pointer-events: none;
}

/* ZOOM TITLE ON HOVER */
.card-wrapper:hover .overlay-title-text,
.category-card-wrapper:hover .overlay-title-text {
  transform: scale(1.15) translateZ(0) !important;
}

/* Touch Device Optimization: Disable Zoom */
@media (hover: none) {

  .card-wrapper:hover .overlay-title-text,
  .category-card-wrapper:hover .overlay-title-text {
    transform: scale(1) translateZ(0) !important;
  }
}

.category-title {
  font-size: clamp(var(--mini-title-floor), 4.87cqi, 1.25rem); /* 20/410.7 */
  font-weight: bold;
  margin-bottom: 1.95cqi; /* 0.5rem */
}

.category-description {
  font-family: var(--font-mono);
  font-size: clamp(var(--blog-desc-floor), 3.51cqi, 0.9rem); /* 14.4/410.7 */
  margin-bottom: 2.43cqi; /* 1rem */
  color: var(--heading-color);
  /* color: var(--accent-color); */

  &.prominent {
    font-size: clamp(var(--blog-desc-floor), 3.9cqi, 1rem); /* 16/410.7 */
    font-weight: 600;
  }

  transition: color 0.3s ease;
}

.category-card-wrapper:hover {
  .category-description:not(.prominent) {
    color: var(--accent-color);
  }
}

.category-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 1.22cqi; /* 0.5rem */
  margin-top: auto;
  /* Push to bottom */
}

.category-tags .badge {
  font-size: clamp(var(--blog-tag-floor), 2.92cqi, 0.75rem); /* 12/410.7 */
  border-radius: 0.73cqi; /* 3px */
  padding: 0.97cqi 1.95cqi; /* 4px 8px */
}



/* Stretched Link & Interactions */
.category-card {
  position: relative;
  /* Ensure card is checking context */
}

.card-link-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  /* Below interactive elements */
}

/* Ensure interactive elements inside are clickable */
.category-tags,
.category-description,
.category-title {
  position: relative;
  z-index: 2;
  pointer-events: none;
  /* Allow clicks to pass through to the card link */
}

.latest-posts {
  position: relative;
  z-index: 2;
  margin-top: 5.84cqi; /* 1.5rem */
  padding-top: 6.23cqi; /* 1.6rem */
  /* Keep default pointer-events (auto) so empty areas capture clicks if desired,
     but user specifically wanted TOP part to be clickable.
     If user wants empty latest-posts area to act as dead zone, we leave it auto. */
  border-top: 1px solid var(--card-border);

  /* Second line for double-border effect with custom gap */
  /* &::before {
     content: "";
     position: absolute;
     top: 4px;
     (1px border + 3px gap)
     left: 0;
     width: 100%;
     height: 1px;
     background-color: var(--card-border, rgba(0, 0, 0, 0.1));
   } */

  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}

.latest-posts-separator {
  /* Optional: Could use this for a styled line if border-top is not enough */
}

.no-posts-message {
  font-size: clamp(0.6875rem, 3.12cqi, 0.8rem); /* 0.8rem at master */
  color: color-mix(in srgb, var(--default-color), transparent 40%);
  font-style: italic;
}

.latest-posts-list {
  list-style: none;
  padding: 0;
  margin: 0;

  li {
    margin-bottom: 2.72cqi; /* 0.7rem */
    font-size: clamp(var(--latest-link-floor), 3.51cqi, 0.9rem); /* 0.9rem */
    font-weight: 500;

    &:last-child {
      margin-bottom: 0;
    }
  }

  /* The Link is now the Flex Container */
  a.recent-post-link {
    color: var(--accent-color);
    text-decoration: none !important;
    /* TARGET SPECIFIC PROPERTIES to avoid animating 'transform' or 'all' which causes re-rasterization */
    transition: color 0.2s ease-out;

    &:hover, &:focus {
      text-decoration: none !important;
    }

    /* Fix text anti-aliasing jitter:
       Remove backface-visibility/transform on the text link itself if it's not moving,
       as that forces a blurrier GPU layer.
    */
    -webkit-font-smoothing: subpixel-antialiased;
    -moz-osx-font-smoothing: grayscale;
    /* Fix Firefox text weight variance */

    display: flex;
    justify-content: space-between;
    align-items: flex-end; /* date sits beside the title's LAST line */
    gap: 1rem;
    width: 100%;

    .post-title {
      text-decoration: underline;
      text-decoration-color: var(--underline-color);
      text-underline-offset: 2px;
      /* Clamp: long post titles (e.g. 75-char fan-post headlines) —
         3 rows on phones, 2 on ≥768px; the date stays fixed right. */
      display: -webkit-box;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 2; /* 2 rows at every width — 3 read as weird */
      overflow: hidden;
      min-width: 0;
    }

    /* Target Title specifically for color change on hover */
    &:hover .post-title {
      color: var(--heading-color);
    }

    /* Target Date specifically for color change */
    &:hover .post-date {
      color: var(--default-color);
    }
  }

  .post-date {
    /* THE DATE — floor wired to --latest-link-floor (the dial you
       were looking for in the block above). */
    font-size: clamp(var(--latest-link-floor), 2.92cqi, 0.75rem); /* 0.75rem */
    text-decoration: none !important;
    /* Never underline the date */
    display: inline-block;
    color: color-mix(in srgb, var(--default-color), transparent 50%);
    white-space: nowrap;
    flex-shrink: 0;
    transition: color 0.2s ease;
  }
}


/* Mini Category Card */
/* Mini category card: fixed master shape 403×113, internals in cqi
   (measured @1920×1080: title 20→4.87, desc 15.2→3.70, badge 11.2→2.73).
   On phones the stack fills the neighboring big card's slot instead
   (see the mobile block) — the fill geometry derives the ratio there. */
.card-base.mini-category-card {
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* Center content vertically if brief */
  border-radius: 2.92cqi; /* 12px at master — compound beats the
                             fixed 0.75rem on .card-base */
  /* Fixed master shape, WIDTH-driven: height must stay auto or a
     stretched grid row (minis dissolved beside tall big cards at
     768-1023px) flips the ratio into a 1398px-wide blowout.
     (h-full was removed from the markup — the utilities layer beats
     component CSS, so the height is owned here.) */
  aspect-ratio: 403 / 113;
  height: auto;
  padding: var(--mini-card-padding-y) 0;
  /* Drastically reduced padding */
  position: relative;
  text-decoration: none;

  &:hover, &:focus {
    text-decoration: none;
  }

  /* Remove default inner card padding so variable controls everything */
  .card-content {
    padding: 0 5.84cqi;
    /* Remove vertical, keep default horizontal (1.5rem at master) */
    /* Center the text block vertically (the card's own
       justify-content only centers the single filling wrapper). */
    justify-content: center;
  }

  .category-title {
    /* Size/spacing inherited from the proportional base rule */
    /* Restored to match standard */
    margin-top: 0;
    color: var(--heading-color);
    transition: color 0.3s ease;
    line-height: 1.2;

    /* Force white in dark mode if variable fails */
    @media (prefers-color-scheme: dark) {
      :root:not(:has(.theme-state-light:checked)) & {
        color: #ffffff !important;
      }
    }

    @media (prefers-color-scheme: light) {
      :root:has(.theme-state-dark:checked) & {
        color: #ffffff !important;
      }
    }
  }

  .category-description {
    font-size: clamp(var(--mini-desc-floor), 3.7cqi, 0.95rem); /* 15.2/410.7 */
    color: color-mix(in srgb, currentColor, transparent 20%);
    margin-bottom: 2.43cqi; /* 1rem */
    /* Restored to match standard */
    line-height: 1.4;
  }

  .category-tags {
    margin-top: 0;
    /* Removing auto margin to keep it compact if needed, or keep auto if height is fixed */
    margin-top: auto;

    .badge {
      font-size: clamp(var(--mini-tag-floor), 2.73cqi, 0.7rem); /* 11.2/410.7 */
      border-radius: 0.73cqi;
      padding: 0.37cqi 0.97cqi; /* 0.15rem 0.4rem */
    }
  }

  /* Interaction: Hover */
  &:hover {
    .category-description {
      color: var(--accent-color);
    }

    /* Title remains static color as requested */
  }
}

/* ====================================================
   === MOBILE DENSITY (phones only, <768px) ===
   2-column grid for both big and mini category cards,
   compact card interiors, shorter image window.
   Odd counts center the last card (2+1 layout).
   ==================================================== */
@media (max-width: 1023px) {
  .blog-categories-section {
    --grid-gap: 1rem;
    --mini-group-gap: 1.5rem;
  }

  /* Card internals are fully proportional via the unified cqi rules —
     no per-breakpoint variants. Only the ARRANGEMENT differs below the
     3-col grid: minis stack in the main grid's leftover slot and FILL
     it, so the stack's bottom edge exactly meets the neighboring big
     card's bottom edge at every width (equal-share geometry; the
     per-mini ratio is derived, not hand-picked — a documented
     fixed-ratio override). Without this, dissolved minis would float
     tiny beside tall big cards in the 2-col grid. */
  .mini-stack-cell {
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }

  .mini-stack-cell .mini-category-card-wrapper {
    flex: 1 1 0;
    min-height: 0;
  }

  .mini-stack-cell .mini-category-card {
    aspect-ratio: auto;
    height: 100%;
    min-height: 0;
  }
}

@media (max-width: 767px) {
  .blog-categories-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Compact-ratio override (constitution §3: fixed new ratio per
   override) — below the 3-col grid the readability floors make the
   content taller than the master shape allows (desc wraps to 4-5
   lines on 140-340px cards). Active for the whole 2-col range. */
@media (max-width: 1023px) {
  .category-card-wrapper .card-base {
    aspect-ratio: var(--blog-phone-ratio);
  }
}

@media (max-width: 479px) {
  .category-card-wrapper .card-base {
    aspect-ratio: var(--blog-narrow-ratio);
  }
}

/* NOTE: no line-clamp on .category-description at narrow widths —
   descriptions are content; the cards grow and the grid row absorbs
   the height. A 3-line cap read as an accidental cut on long
   descriptions (Permaculture). */

/* ≥768px: dissolve the stack cell so minis flow as their own row in the
   main grid (replaces the old dedicated mini-categories container). The
   wrapper margin restores the group gap that container used to provide. */
@media (min-width: 1024px) {
  .mini-stack-cell {
    display: contents;
  }

  .mini-stack-cell > .mini-category-card-wrapper {
    /* The main grid's row-gap stacks on top of this margin — subtract it
       so the visual group gap matches the old dedicated container (--grid-gap). */
    margin-top: calc(var(--mini-group-gap, 5rem) - var(--grid-gap, 2rem));
  }
}
}/* Card-facing post primitives (.post-header/.post-title/.meta-top) render here too,
     so this partial ships wherever those cards appear. */
@layer components {

/*
 * SPDX-FileCopyrightText: 2026 The freelance-persona_theme Project Contributors
 *
 * SPDX-License-Identifier: MIT
 */

/*--------------------------------------------------------------
# Blog Post Section
--------------------------------------------------------------*/
.blog-post {
  padding-bottom: 1.875rem; /* 30px */
  margin: 0; /* Spacing handled by .section padding-top */
}

.blog-post .article {
  padding: 1.875rem; /* 30px */
  box-shadow: 0 0.25rem 1rem color-mix(in srgb, var(--default-color), transparent 90%); /* 0 4px 16px */
}

.blog-post .post-img {
  /* margin: -1.875rem -1.875rem 1.25rem -1.875rem; // -30px -30px 20px -30px */
  margin: 0 0 1.25rem 0;
  overflow: hidden;
  border-radius: 0.25rem;
  aspect-ratio: 16/9;
  position: relative; /* For attribution overlay positioning */

  /* Attribution scales with the image; the wrapper is the query
     container (inline-size) so the rail/overlay can use cqi.
     1.3cqi ≈ the pre-proportional 0.65rem at desktop article width —
     the 2.34cqi card ratio overscaled on full-width post images. */
  container-type: inline-size;
  --attribution-font-size: max(1.3cqi, var(--attribution-min-size));

  img {
    width: 100%;
    height: 100%;
    object-fit: cover;

    /* Mute brightness in dark mode to avoid glare */
    @media (prefers-color-scheme: dark) {
      :root:not(:has(.theme-state-light:checked)) & {
        filter: brightness(0.85) contrast(1.1);
        transition: filter 0.3s ease;
      }
    }

    @media (prefers-color-scheme: light) {
      :root:has(.theme-state-dark:checked) & {
        filter: brightness(0.85) contrast(1.1);
        transition: filter 0.3s ease;
      }
    }
  }
}

/* Hover to restore full brightness for hero image */
@media (prefers-color-scheme: dark) {
  :root:not(:has(.theme-state-light:checked)) .blog-post .post-img img:hover {
    filter: brightness(1) contrast(1);
  }
}

@media (prefers-color-scheme: light) {
  :root:has(.theme-state-dark:checked) .blog-post .post-img img:hover {
    filter: brightness(1) contrast(1);
  }
}

.blog-post .title {
  color: var(--heading-color);
  font-size: 1.75rem; /* 28px */
  font-weight: 700;
  padding: 0;
  margin: 1.875rem 0; /* 30px 0 */
}

.blog-post .post-content {
  margin-top: 1.25rem; /* 20px */
  display: flow-root;
}

.blog-post .post-content p {
  text-align: justify;
}

.blog-post .post-content img {
  max-width: 100%;
  height: auto;
  display: block;
  border-radius: 0.25rem; /* 4px */
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--default-color), transparent 85%);
  margin-left: auto;
  margin-right: auto;
  margin-bottom: 1.25rem; /* 20px */
  margin-top: 0.625rem; /* 10px */
}

.blog-post .post-content svg {
  max-width: 100%;
  height: auto;
  display: block;
  margin-left: auto;
  margin-right: auto;
  margin-bottom: 1.25rem; /* 20px */
  margin-top: 0.625rem; /* 10px */
}

.blog-post .post-content.science-layout {
  text-align: justify;

  p {
    margin-bottom: 1.25rem;
    line-height: 1.6;
  }

  @media (min-width: 768px) {
    column-count: 2;
    column-gap: 2.5rem;
    column-rule: 1px solid color-mix(in srgb, var(--default-color), transparent 90%);

    h3, blockquote, table, iframe, pre, .expressive-code {
      column-span: all;
    }

    svg, img {
      &[style*="margin: 1.5rem auto"], &[style*="margin:1.5rem auto"] {
        column-span: all;
        max-width: 60%;
        margin: 2.5rem auto;
      }
    }
  }
}

.blog-post .post-content h3 {
  font-size: 1.375rem; /* 22px */
  margin-top: 1.875rem; /* 30px */
  font-weight: bold;
}

.blog-post .post-content table {
  /* Tables can't shrink below min-content — block + scroll keeps wide
     tables INSIDE the article instead of overflowing the page (which
     made mobile browsers zoom out and shrink everything). */
  display: block;
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  border-collapse: collapse;
  margin: 1.25rem 0; /* 20px 0 */
  background-color: var(--surface-color);
  text-align: left;
}

.blog-post .post-content th {
  border-bottom: 2px solid color-mix(in srgb, var(--default-color), transparent 80%);
  background-color: color-mix(in srgb, var(--default-color), transparent 95%);
  color: var(--heading-color);
  padding: 0.75rem; /* 12px */
}

.blog-post .post-content td {
  border-bottom: 1px solid color-mix(in srgb, var(--default-color), transparent 90%);
  padding: 0.75rem; /* 12px */
}

.blog-post .post-content tr:nth-child(even) td {
  background-color: color-mix(in srgb, var(--default-color), transparent 97%);
}

.blog-post .post-content tr:hover td {
  background-color: color-mix(in srgb, var(--default-color), transparent 95%);
}

/* ====================================================
   === MOBILE TABLE TREATMENTS (phones only, ≤767px) ===
   Markdown tables can't shrink below min-content; the base
   block+scroll above keeps them inside the article but hides
   columns with zero affordance. The treatment is selected via
   visuals.tables.mobile_style (body[data-tables-mobile]):
   - cards (default): each row becomes a self-describing card —
     remarkTableDataLabels copies the column headers into
     data-label attributes
   - scroll: the grid stays, first column pinned, right-edge
     fade as the scroll affordance (the tag-rail peek idiom)
   - native: no extra rules (base block+scroll only)
   ==================================================== */
@media (max-width: 767px) {
  /* --- "cards": labeled row cards, no horizontal scroll --- */
  body[data-tables-mobile="cards"] .blog-post .post-content table {
    display: block;
    border-collapse: separate;
    background-color: transparent;
  }

  body[data-tables-mobile="cards"] .blog-post .post-content thead {
    display: none; /* column names live on each cell as data-label */
  }

  body[data-tables-mobile="cards"] .blog-post .post-content tbody {
    display: block;
  }

  body[data-tables-mobile="cards"] .blog-post .post-content tbody tr {
    display: block;
    background-color: var(--surface-color);
    border: 1px solid var(--card-border);
    border-radius: 0.375rem;
    padding: 0.75rem 1rem;
    margin-bottom: 0.75rem;
  }

  body[data-tables-mobile="cards"] .blog-post .post-content tbody tr:last-child {
    margin-bottom: 0;
  }

  body[data-tables-mobile="cards"] .blog-post .post-content tbody td {
    display: block;
    padding: 0.25rem 0;
    border-bottom: none;
    background-color: transparent;
  }

  body[data-tables-mobile="cards"] .blog-post .post-content tbody tr:last-child td:last-child {
    border-bottom: none;
  }

  /* Column label as an overline above each cell's content. */
  body[data-tables-mobile="cards"] .blog-post .post-content tbody td::before {
    content: attr(data-label);
    display: block;
    font-family: var(--font-mono, monospace);
    font-size: 0.6875rem; /* 11px */
    font-weight: 500;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--default-color), transparent 45%);
    margin-bottom: 0.125rem;
  }

  /* --- Per-column accents: visual anchors so grouped columns
     (e.g. two colony columns in a schedule table) are pattern-
     scannable. Each column gets a hue for its label and a soft
     left bar on its blocks; the first column stays the neutral
     card header. Override any column via the custom properties,
     e.g. --table-col-3-color: #d97706. --- */
  body[data-tables-mobile="cards"] .blog-post .post-content tbody td:nth-child(2) {
    --table-col-color: var(--table-col-2-color, #0284c7); /* sky-600 */
  }

  body[data-tables-mobile="cards"] .blog-post .post-content tbody td:nth-child(3) {
    --table-col-color: var(--table-col-3-color, #d97706); /* amber-600 */
  }

  body[data-tables-mobile="cards"] .blog-post .post-content tbody td:nth-child(4) {
    --table-col-color: var(--table-col-4-color, #16a34a); /* green-600 */
  }

  body[data-tables-mobile="cards"] .blog-post .post-content tbody td:nth-child(5) {
    --table-col-color: var(--table-col-5-color, #dc2626); /* red-600 */
  }

  body[data-tables-mobile="cards"] .blog-post .post-content tbody td:nth-child(6) {
    --table-col-color: var(--table-col-6-color, #7c3aed); /* violet-600 */
  }

  body[data-tables-mobile="cards"] .blog-post .post-content tbody td:nth-child(7) {
    --table-col-color: var(--table-col-7-color, #0284c7);
  }

  body[data-tables-mobile="cards"] .blog-post .post-content tbody td:nth-child(8) {
    --table-col-color: var(--table-col-8-color, #d97706);
  }

  body[data-tables-mobile="cards"] .blog-post .post-content tbody td:nth-child(n + 2) {
    border-left: 0.1875rem solid color-mix(in srgb, var(--table-col-color, var(--accent-color)), transparent 60%);
    padding-left: 0.5rem;
  }

  body[data-tables-mobile="cards"] .blog-post .post-content tbody td:nth-child(n + 2)::before {
    color: var(--table-col-color, color-mix(in srgb, var(--default-color), transparent 45%));
  }

  /* First column = the row identifier ("Day 0 — The Split"):
     emphasize it as the card header. */
  body[data-tables-mobile="cards"] .blog-post .post-content tbody td:first-child {
    padding-bottom: 0.5rem;
    margin-bottom: 0.25rem;
    border-bottom: 1px solid color-mix(in srgb, var(--default-color), transparent 90%);
    color: var(--heading-color);
    font-weight: 700;
  }

  body[data-tables-mobile="cards"] .blog-post .post-content tbody td:first-child strong {
    color: var(--accent-color);
  }

  /* --- "scroll": compact data-grid for structured content
     (statistics, price lists — content that reads like a sheet).
     Dense typography, pinned first column, thin column separators,
     right-edge fade as the swipe affordance (the tag-rail peek
     idiom). Note: a sticky TOP header row is impossible inside an
     overflow-x scroll container (the spec forces overflow-y to auto,
     so there is no page-scroll to stick against) — the header row
     scrolls away vertically by design. */
  body[data-tables-mobile="scroll"] .blog-post .post-content table {
    font-size: 0.8125rem; /* 13px — sheet-density body */
    -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 1.5rem), transparent);
    mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 1.5rem), transparent);
  }

  body[data-tables-mobile="scroll"] .blog-post .post-content th {
    padding: 0.5rem 0.625rem; /* 8px 10px */
    background-color: var(--surface-color); /* solid: sticky head */
    border-bottom: 2px solid color-mix(in srgb, var(--default-color), transparent 75%);
    font-weight: 700;
    white-space: nowrap;
  }

  body[data-tables-mobile="scroll"] .blog-post .post-content td {
    padding: 0.5rem 0.625rem;
    border-bottom: 1px solid color-mix(in srgb, var(--default-color), transparent 90%);
  }

  /* Thin column separators give the grid its spreadsheet feel. */
  body[data-tables-mobile="scroll"] .blog-post .post-content th:not(:first-child),
  body[data-tables-mobile="scroll"] .blog-post .post-content td:not(:first-child) {
    border-left: 1px solid color-mix(in srgb, var(--default-color), transparent 88%);
  }

  /* Pinned first column: row identifiers stay readable while the
     remaining columns scroll. box-shadow instead of border — with
     border-collapse the td borders live on the table and would not
     travel with a sticky cell. */
  body[data-tables-mobile="scroll"] .blog-post .post-content th:first-child,
  body[data-tables-mobile="scroll"] .blog-post .post-content td:first-child {
    position: sticky;
    left: 0;
    background-color: var(--surface-color);
    font-weight: 600;
    z-index: 1;
    box-shadow: inset -1px 0 0 color-mix(in srgb, var(--default-color), transparent 88%);
  }

  /* Zebra rows must stay behind the pinned column: use the opaque
     composite so the sticky cell doesn't turn see-through. */
  body[data-tables-mobile="scroll"] .blog-post .post-content tr:nth-child(even) td:first-child {
    background-color: color-mix(in srgb, var(--default-color) 3%, var(--surface-color));
  }

  body[data-tables-mobile="scroll"] .blog-post .post-content thead th:first-child {
    z-index: 2; /* corner cell above pinned tds */
  }
}

/* Quote — paragraph-friendly: the accent bar (blockquote:after)
   is the signature; text sits left and reads like prose. For the
   big centered "pop" look use the :::pullquote directive instead. */
.blog-post .post-content blockquote {
  overflow: hidden;
  background-color: color-mix(in srgb, var(--default-color), transparent 95%);
  padding: 1rem 1.25rem;
  position: relative;
  text-align: left;
  margin: 1.25rem 0; /* 20px 0 */
}

.blog-post .post-content blockquote p {
  color: var(--default-color);
  line-height: 1.6;
  margin-bottom: 0;
  font-style: italic;
  font-weight: 400;
  font-size: 1.0625rem; /* 17px */
  text-align: left;
}

/* Opt-in pop quote (:::pullquote) — one-liners meant to stand out. */
.blog-post .post-content blockquote.pullquote {
  text-align: center;
  padding: 1.875rem; /* 30px */
}

.blog-post .post-content blockquote.pullquote p {
  font-size: 1.375rem; /* 22px */
  font-weight: 500;
  text-align: center;
}

.blog-post .post-content blockquote:after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 0.1875rem; /* 3px */
  background-color: var(--accent-color);
  margin-top: 1.25rem; /* 20px */
  margin-bottom: 1.25rem; /* 20px */
}

/* ====================================================
   === ADMONITIONS (markdown container directives) ===
   :::warning[Title] … ::: / :::tip / :::info / :::note /
   :::important / :::caution — semantic hues are fixed on
   purpose (universal callout semantics); transparency keeps
   them dark-mode safe. See docs/features/admonitions.md.
   ==================================================== */
.blog-post .post-content .admonition {
  --admonition-color: var(--accent-color);
  margin: 1.25rem 0; /* 20px 0 */
  padding: 1rem 1.25rem;
  border-left: 0.1875rem solid var(--admonition-color);
  background-color: color-mix(in srgb, var(--admonition-color), transparent 92%);
  border-radius: 0.375rem;
  overflow: hidden;
}

.blog-post .post-content .admonition p {
  margin-bottom: 0.5rem;
  line-height: 1.6;
  text-align: left;
}

.blog-post .post-content .admonition p:last-child {
  margin-bottom: 0;
}

.blog-post .post-content .admonition-title {
  margin: 0 0 0.5rem !important;
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--admonition-color);
}

/* The bracket line (:::info[Subtitle]) — follows the theme's subtitle
   idiom (mono, size/weight like .section-title em) but takes the
   admonition's semantic hue instead of the accent, matching the type
   title above it. */
.blog-post .post-content .admonition .admonition-subtitle {
  margin: 0 0 0.75rem;
  font-family: var(--font-mono, monospace);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--admonition-color);
}

.blog-post .post-content .admonition.admonition-warning {
  --admonition-color: #d97706; /* amber-600: readable on both themes */
}

.blog-post .post-content .admonition.admonition-caution {
  --admonition-color: #dc2626; /* red-600 */
}

.blog-post .post-content .admonition.admonition-tip {
  --admonition-color: #16a34a; /* green-600 */
}

.blog-post .post-content .admonition.admonition-info {
  --admonition-color: #0284c7; /* sky-600 */
}

.blog-post .post-content .admonition.admonition-note {
  --admonition-color: var(--default-color);
}

/* meta top styles */

.meta-top-divider {
  height: 1px;
  background-color: color-mix(in srgb, var(--default-color), transparent 85%);
  margin: 0.625rem 0; /* 10px 0 */
  padding: 0;
}

.blog-post .meta-top {
  margin-top: 0.625rem; /* 10px */
  color: color-mix(in srgb, var(--default-color), transparent 40%);
  margin-bottom: 0.625rem; /* 10px */
}

.blog-post .meta-top ul {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  align-items: center;
  padding: 0;
  margin: 0;
}

.blog-post .meta-top #info li+li {
  padding-left: 1.25rem; /* 20px */
}

.blog-post .meta-top #action li+li {
  padding-left: 0.625rem; /* 10px */
}

.blog-post .meta-top #info li [data-icon] {
  font-size: 1rem; /* 16px */
  margin-right: 0.5rem; /* 8px */
  line-height: 0;
  color: color-mix(in srgb, var(--default-color), transparent 40%);
}

.blog-post .meta-top time,
.blog-post .meta-top span {
  color: color-mix(in srgb, var(--default-color), transparent 40%);
  font-size: 0.875rem; /* 14px */
  display: inline-block;
  line-height: 1;
}

.blog-post .meta-bottom {
  padding-top: 0.625rem; /* 10px */
  border-top: 1px solid color-mix(in srgb, var(--default-color), transparent 90%);
}

.blog-post .meta-bottom [data-icon] {
  color: color-mix(in srgb, var(--default-color), transparent 40%);
  display: inline;
}

.blog-post .meta-bottom a {
  color: color-mix(in srgb, var(--default-color), transparent 40%);
  transition: 0.3s;
}

.blog-post .meta-bottom a:hover {
  color: var(--accent-color);
}

.blog-post .meta-bottom .cats {
  list-style: none;
  display: inline;
  padding: 0 1.25rem 0 0; /* 0 20px 0 0 */
  font-size: 0.875rem; /* 14px */
}

.blog-post .meta-bottom .cats li {
  display: inline-block;
}

.blog-post .meta-bottom .tags {
  list-style: none;
  display: inline;
  padding: 0;
  font-size: 0.875rem; /* 14px */
}

.blog-post .meta-bottom .tags li {
  display: inline-block;
}

.blog-post .meta-bottom .tags li+li::before {
  padding-right: 0.375rem; /* 6px */
  color: var(--default-color);
  content: ",";
}

.blog-post .meta-bottom .share {
  font-size: 1rem; /* 16px */
}

.blog-post .meta-bottom .share [data-icon] {
  padding-left: 0.3125rem; /* 5px */
}


.blog-post .post-top-content img,
.blog-post .post-content img {
  border-radius: 0.25rem; /* 4px */

  /* Mute brightness in dark mode to avoid glare */
  @media (prefers-color-scheme: dark) {
    :root:not(:has(.theme-state-light:checked)) & {
      filter: brightness(0.85) contrast(1.1);
      transition: filter 0.3s ease;
    }
  }

  @media (prefers-color-scheme: light) {
    :root:has(.theme-state-dark:checked) & {
      filter: brightness(0.85) contrast(1.1);
      transition: filter 0.3s ease;
    }
  }
}

/* Hover to restore full brightness */
@media (prefers-color-scheme: dark) {
  :root:not(:has(.theme-state-light:checked)) .blog-post img:hover {
    filter: brightness(1) contrast(1);
  }
}

@media (prefers-color-scheme: light) {
  :root:has(.theme-state-dark:checked) .blog-post img:hover {
    filter: brightness(1) contrast(1);
  }
}

.blog-post .post-tags {
  margin-top: 0.5em;
  position: relative;
  transition: max-height 0.35s ease-out;
}

/* ============================================================
   Clamped post tags — native reveal/collapse (checkbox pattern,
   theme-consistent with the radio theme switcher; works without JS).
   1 row on mobile, 2 on desktop; the label renders server-side only
   when the tag count can overflow (BlogPostTemplate).
   ============================================================ */
.blog-post {
  --post-tags-clamp: 1.75rem;      /* mobile: 1 badge row */
  --post-tags-clamp-desktop: 3.5rem; /* desktop: 2 rows */
}

@media (min-width: 768px) {
  .blog-post {
    --post-tags-clamp: var(--post-tags-clamp-desktop);
  }
}

.blog-post .tags-toggle-cb {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* Collapsed: 1 row (mobile) / 2 rows (desktop) fully crisp, plus a
   small PEEK strip where the next row's badge tops fade out (real
   hidden tags, not a fake hint) — via mask, so there is no overlay
   gradient (a gradient read as a dirty shadow in the dark theme).
   The toggle label sits centered below. */
.blog-post .tags-toggle-cb:not(:checked) ~ .post-tags {
  max-height: calc(var(--post-tags-clamp) + var(--post-tags-peek, 0.625rem));
  overflow: hidden;
  mask-image: linear-gradient(
    to bottom,
    #000 calc(100% - var(--post-tags-peek, 0.625rem)),
    transparent
  );
}

/* Expanded */
.blog-post .tags-toggle-cb:checked ~ .post-tags {
  max-height: 40rem;
}

/* Toggle label — subtitle idiom (mono + accent) */
.blog-post .tags-toggle {
  /* Full row + centered: sits under the tag block, aligned with it */
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  gap: 0.5rem;
  margin-top: 0.375rem;
  font-family: var(--font-mono, monospace);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--accent-color);
  cursor: pointer;
  user-select: none;
}

.blog-post .tags-toggle .tags-chevron {
  display: inline-block;
  transition: transform 0.35s ease-out;
}

.blog-post .tags-toggle-cb:checked ~ .tags-toggle .tags-chevron {
  transform: rotate(180deg);
}

.blog-post .tags-toggle .when-open {
  display: none;
}

.blog-post .tags-toggle-cb:checked ~ .tags-toggle .when-closed {
  display: none;
}

.blog-post .tags-toggle-cb:checked ~ .tags-toggle .when-open {
  display: inline;
}

/* The label renders per tag count: 4–10 = mobile only (desktop fits
   two rows), ≥11 = always. ≤3: no label at all. */
.blog-post .tags-toggle--mobile-only {
  display: none;
}

@media (max-width: 767px) {
  .blog-post .tags-toggle--mobile-only {
    display: inline-flex;
  }
}

/* Keyboard: focus ring on the label when the hidden checkbox focuses */
.blog-post .tags-toggle-cb:focus-visible ~ .tags-toggle {
  outline: 2px solid var(--accent-color);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .blog-post .post-tags,
  .blog-post .tags-toggle .tags-chevron {
    transition: none;
  }
}



.blog-post .post-content {
  margin-top: 2em;
}

#blog-post {
  position: relative;
  z-index: 10;
}

/* Post header layout */
.post-header {
  margin-bottom: 2em;
  position: relative;
  z-index: 5;
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 0.5em;
}

.post-title {
  margin: 0;
  flex: 1;
}

.MathJax {
  overflow-x: auto;
  overflow-y: hidden;
  max-width: 100%;
}

.post-content .mjx-chtml {
  margin: 1em 0;
}

.post-content .mjx-chtml.MJXc-display {
  margin: 1.5em 0;
  padding: 0;
}

/* Ensure equation numbers are visible */
.post-content .mjx-chtml .mjx-right {
  margin-right: 0 !important;
  float: right !important;
  text-align: right !important;
}

/* LaTeX equation overflow handling with centered content */
.post-content .MathJax_Display,
.post-content .mjx-chtml.MJXc-display {
  overflow-x: auto;
  overflow-y: hidden;
  margin: 1em 0;
  padding: 0.5em 0;
  width: 100% !important;
  /* Force width to ensure scrollbar works */
  max-width: 100%;
  display: flex !important;
  /* Use flexbox for centering */
  justify-content: center !important;
}

/* Center the math content while allowing it to be wider than container */
.post-content .mjx-chtml .mjx-math {
  min-width: min-content !important;
  /* Allow content to determine width */
  display: inline-block !important;
  text-align: center !important;
  margin: 0 auto !important;
}

/* Style the scrollbar for better appearance */
.post-content .mjx-chtml.MJXc-display::-webkit-scrollbar,
.post-content .MathJax_Display::-webkit-scrollbar {
  height: 0.5rem; /* 8px */
}

.post-content .mjx-chtml.MJXc-display::-webkit-scrollbar-track,
.post-content .MathJax_Display::-webkit-scrollbar-track {
  background: var(--scrollbar-track);
  border-radius: 4px;
}

.post-content .mjx-chtml.MJXc-display::-webkit-scrollbar-thumb,
.post-content .MathJax_Display::-webkit-scrollbar-thumb {
  background: var(--scrollbar-thumb);
  border-radius: 4px;
}

.post-content .mjx-chtml.MJXc-display::-webkit-scrollbar-thumb:hover,
.post-content .MathJax_Display::-webkit-scrollbar-thumb:hover {
  background: var(--scrollbar-thumb-hover);
}

/* Ensure equation container doesn't overflow */
.post-content .MathJax_SVG_Display,
.post-content .MathJax {
  max-width: 100%;
}

/* Ensure container for equations has proper overflow */
.post-content .mjx-container {
  overflow-x: auto;
  overflow-y: hidden;
  max-width: 100%;
}

/* Figure-wrapper alignment: paragraphs inside .text-center/.text-end
   wrappers (used by post content for figure grouping) follow the
   wrapper's alignment instead of the post-wide justified text. */
.text-center p, .text-end p, .text-start p {
  text-align: inherit !important;
}
}/* Component-owned styles (shipped only when this component is used) */

@layer components {

/*
 * SPDX-FileCopyrightText: 2026 The freelance-persona_theme Project Contributors
 *
 * SPDX-License-Identifier: MIT
 */

/*--------------------------------------------------------------
# About Section Styles
# Extracted from AboutSection.astro inline styles
--------------------------------------------------------------*/

.about.section {
    transform: translate(var(--nudge-x, 0), var(--nudge-y, 0)) scale(var(--content-scale, 1));
    margin-bottom: 3rem;
    /* Add spacing to prevent crowding */
    overflow: visible;
    /* Allow float to hang out */
}

/* Ensure content container hugs the text bottom */
.content.main-content> :last-child {
    margin-bottom: 0 !important;
}

/* Mobile Stacked Layout (Default) */
.container-grid {
    display: flex;
    flex-direction: column;
    gap: 2rem;
}

.qualifications-sidebar {
    order: -1;
    /* Sidebar TOP on mobile */
    width: 100%;
    margin-top: 2rem;
    z-index: 1;
}

.sidebar-content-wrapper {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
}


/* Desktop Float Layout */
@media (min-width: 992px) {
    .container-grid {
        display: block;
        /* Disable Flex/Grid to allow float */
    }

    .qualifications-sidebar {
        float: right;
        width: fit-content;
        clear: right;
        order: unset;

        /* Apply dynamic positioning variables.
           NOTE: offsets are CONTAINER-EDGE-RELATIVE (rem) — they scale
           with the fluid root dial and default 0 aligns the sidebar's
           outer edge flush with every other section's container edge.
           The old screen-edge formula (calc(((100% - 100vw) / 2) + Xrem))
           mixed vw with rem and drifted apart below the dial's floor
           zone (rem frozen at 12.8px while the viewport kept shrinking) */
        z-index: var(--z-index);
        margin-top: var(--float-margin-top);
        margin-right: var(--float-margin-right);
        margin-left: var(--float-margin-left);
        margin-bottom: var(--float-margin-bottom);
        position: relative;
    }

    .sidebar-content-wrapper {
        width: fit-content;
        align-items: center;
    }

    .content.main-content {
        display: block;
        width: 100%;
        order: unset;
    }
}

/* Avatar Styling */
.avatar-container {
    display: flex;
    justify-content: center;
    margin-bottom: 2rem;
    flex-shrink: 0;
    /* Prevent avatar from squishing */
    position: relative;
    /* For attribution positioning */

    /* Size override for avatar attribution */
    --attribution-font-size: 0.55rem;

    /* Import attribution base styles FIRST */

    /* Then override positioning for avatar context */
    .img-attribution {
        /* Anchor to top-left of the desired area so it grows Right and Down */
        top: 96%; /* Move further down (was 85%) */
        left: 75%;
        bottom: auto;
        right: auto;

        flex-direction: column;
        align-items: flex-start; /* Align text to left */
        text-align: left;
        gap: 0;

        white-space: nowrap; /* Prevent eager wrapping */
    }
}

.avatar-image {
    /* rem (not px) so the avatar scales with the fluid root dial */
    width: 12.5rem;
    height: 12.5rem;
    border-radius: 50%;
    object-fit: cover;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
    border: 0.25rem solid var(--surface-color, #fff);
    background-color: var(--surface-color, #fff);
    /* Prevents bleed-through */
}

/* Floating Avatar (when sidebar is disabled) */
.avatar-float {
    /* Mobile Default: Stacked & Centered */
    float: none;
    display: block;
    margin: 0 auto 2rem auto;
    /* Center horizontally, push text down */
    width: 12.5rem;
    height: 12.5rem;
    border-radius: 50%;
    object-fit: cover;
    z-index: 1;
    position: relative;

    /* Apply styles usually handled by Image but good for wrapper too just in case */
    shape-outside: none;
}

@media (min-width: 992px) {
    .avatar-float {
        float: right;
        margin-top: var(--float-margin-top);
        margin-right: var(--float-margin-right);
        margin-left: var(--float-margin-left);
        shape-outside: var(--shape-outside, circle(50%));
        z-index: var(--z-index);
    }
}

/* Profile Box Styling */
.qualifications-box {
    /* Style matched to .widget-item (Recent Posts) */
    background-color: color-mix(in srgb, var(--default-color), transparent 98%);
    border: 1px solid color-mix(in srgb, var(--default-color), transparent 90%);
    padding: 1.875rem;
    border-radius: 0.3125rem;
    /* Match widget styling (5px) */

    position: relative;
    width: 100%;
    /* controlled by grid column */
    max-width: 20rem;
    margin: 0;
    /* Changed from 0 auto to align left */

    /* Equal Height Logic */
    flex: 1;
    display: flex;
    flex-direction: column;

    transition: transform 0.3s ease;
}

.qualifications-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    /* Increased gap between rows */
}

.qualifications-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.qualifications-item-content,
.qualifications-link {
    display: flex;
    flex-direction: row;
    /* Horizontal layout */
    align-items: center;
    justify-content: flex-start;
    gap: 1rem;
    color: var(--default-color);
    text-decoration: none;
    transition: color 0.3s ease;
    text-align: left;
    flex: 1; /* Take available space */
}

.qualifications-link:hover {
    color: var(--default-color);
    text-decoration: none;
}


/* Large Typography for Sidebar Items */
.qualifications-text {
    font-size: 1.15rem;
    /* Slightly smaller to fit row */
    font-family: var(--font-heading);
    font-weight: 500;
    line-height: 1.2;
    flex: 1;
    /* Allow text to take space */
}

.qualifications-icon {
    font-size: 1.5rem;
    color: var(--accent-color);
    flex-shrink: 0;
}

.qualifications-cert-img {
    width: 3.125rem;
    /* Bigger size */
    height: 3.125rem;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 0.25rem;
    /* Slight roundness */
    overflow: hidden;
    background: #f8f9fa;
    /* Subtle background for transparency */
    border: 1px solid color-mix(in srgb, var(--default-color), transparent 95%);

    /* Animation Performance Optimization (Fix jitter) */
    /* Animation Performance Optimization (Fix jitter) */
    /* Unify Easing to ease-out to prevent desync "hop" */
    transition: transform 0.3s ease-out, box-shadow 0.3s ease-out, border-color 0.3s ease-out;
    will-change: transform;
    backface-visibility: hidden;
    transform: translateZ(0) scale(1.0001) rotate(0.001deg); /* Promote + scale + rotate to force anti-aliasing in FF */
    -webkit-font-smoothing: subpixel-antialiased; /* Fix text jitter */

}



/* Hover Effect Updates for :has() logic */
.qualifications-item:has(.qualifications-link:hover) .qualifications-cert-img,
.qualifications-item:has(.cert-img-only-link:hover) .qualifications-cert-img {
    transform: translateY(-1.5px);
    box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
    border-color: color-mix(in srgb, var(--accent-color), transparent 65%);
}

.qualifications-item:has(.qualifications-link:hover) .qualifications-subtitle,
.qualifications-item:has(.cert-img-only-link:hover) .qualifications-subtitle {
    color: color-mix(in srgb, var(--accent-color), transparent 55%);
}

@media (prefers-color-scheme: dark) {
  :root:not(:has(.theme-state-light:checked)) .qualifications-item:has(.qualifications-link:hover) .qualifications-subtitle,
  :root:not(:has(.theme-state-light:checked)) .qualifications-item:has(.cert-img-only-link:hover) .qualifications-subtitle {
      color: var(--accent-color);
  }
}

@media (prefers-color-scheme: light) {
  :root:has(.theme-state-dark:checked) .qualifications-item:has(.qualifications-link:hover) .qualifications-subtitle,
  :root:has(.theme-state-dark:checked) .qualifications-item:has(.cert-img-only-link:hover) .qualifications-subtitle {
      color: var(--accent-color);
  }
}

.qualifications-cert-img img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* User requested "tiny tiny writing just below the certificate" */
/* User requested "tiny tiny writing just below the certificate" */
.img-attribution.cert-attribution {
    position: static !important;
    margin-top: 0.25rem;
    width: 100%;

    /* FORCE Layout */
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 0 !important;
    text-align: center !important;
    border: none !important;

    /* FORCE Size (Variable isn't cascading reliably?) */
    font-size: 0.35rem !important;
    line-height: 1.1 !important;
    --attribution-font-size: 0.35rem; /* Keep var for consistency if it works */

    /* Ensure children inherit tiny size */
    a,
    span,
    i {
        font-size: inherit !important;
        line-height: inherit !important;
    }

    /* Color Logic (Already confirmed working) */
    --attribution-color: color-mix(in srgb, var(--default-color), transparent 50%);
    color: var(--attribution-color) !important;

    /* Fixed Link Color */
    a {
        color: var(--attribution-color) !important;
        text-decoration: none;
    }

    a:hover {
        text-decoration: underline;
        text-decoration-color: var(--underline-color);
        color: var(--accent-color) !important;
    }
}



/* Subtitles Logic */
.qualifications-text-col {
    display: flex;
    flex-direction: column;
    flex: 1;
    /* Take simplified space */
    justify-content: center;
    margin-right: 0.5rem;
}

.qualifications-subtitle {
    font-size: 0.75em;
    font-weight: 500;
    color: color-mix(in srgb, var(--default-color), transparent 55%);
    line-height: 1.2;
    display: block;
    margin-top: 0.1rem;
    transition: color 0.3s ease;
}



/* Responsive Mobile Tweaks */
@media (max-width: 991px) {
    .qualifications-sidebar {
        margin-top: 3rem;
        display: flex;
        flex-direction: column;
        align-items: center;
    }

    .qualifications-box {
        width: 100%;
        max-width: 350px;
    }
}
}/* Component-owned styles (shipped only when this component is used) */

@layer components {

/*
 * SPDX-FileCopyrightText: 2026 The freelance-persona_theme Project Contributors
 *
 * SPDX-License-Identifier: MIT
 */

/*
 * Home Page Specific Styles
 * Applies distinct background colors for the landing page vs inner pages in Dark Mode.
 */

@media (prefers-color-scheme: dark) {
    :root:not(:has(.theme-state-light:checked)) {

        &.home-page,
        .home-page {
            --background-color: var(--surface-color, #303030) !important;
        }

        &.inner-page,
        .inner-page {
            --background-color: var(--background-color, #1e1e1e) !important;
        }
    }
}

@media (prefers-color-scheme: light) {
    :root:has(.theme-state-dark:checked) {

        &.home-page,
        .home-page {
            --background-color: var(--surface-color, #303030) !important;
        }

        &.inner-page,
        .inner-page {
            --background-color: var(--background-color, #1e1e1e) !important;
        }
    }
}
}/* poppins-latin-300-normal */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(/astro-freelance-persona_theme/_astro/poppins-latin-300-normal.Dku2WoCh.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/poppins-latin-300-normal.DCNuMXUj.woff) format('woff');
}/* poppins-latin-400-normal */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/astro-freelance-persona_theme/_astro/poppins-latin-400-normal.cpxAROuN.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/poppins-latin-400-normal.BOb3E3N0.woff) format('woff');
}/* poppins-latin-500-normal */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/astro-freelance-persona_theme/_astro/poppins-latin-500-normal.C8OXljZJ.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/poppins-latin-500-normal.DGXqpDMm.woff) format('woff');
}/* poppins-latin-600-normal */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/astro-freelance-persona_theme/_astro/poppins-latin-600-normal.zEkxB9Mr.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/poppins-latin-600-normal.BJdTmd5m.woff) format('woff');
}/* poppins-latin-700-normal */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(/astro-freelance-persona_theme/_astro/poppins-latin-700-normal.Qrb0O0WB.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/poppins-latin-700-normal.BVuQR_eA.woff) format('woff');
}/* raleway-latin-300-normal */
@font-face {
  font-family: 'Raleway';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(/astro-freelance-persona_theme/_astro/raleway-latin-300-normal.B0PjX2GJ.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/raleway-latin-300-normal.CA-NUC9Y.woff) format('woff');
}/* raleway-latin-400-normal */
@font-face {
  font-family: 'Raleway';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/astro-freelance-persona_theme/_astro/raleway-latin-400-normal.C5eIEfLm.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/raleway-latin-400-normal.sMcq1OIP.woff) format('woff');
}/* raleway-latin-500-normal */
@font-face {
  font-family: 'Raleway';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/astro-freelance-persona_theme/_astro/raleway-latin-500-normal.D-8sZNrj.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/raleway-latin-500-normal.tXW-zgej.woff) format('woff');
}/* raleway-latin-600-normal */
@font-face {
  font-family: 'Raleway';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/astro-freelance-persona_theme/_astro/raleway-latin-600-normal.Dim-CLtL.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/raleway-latin-600-normal.BYS3Hyhk.woff) format('woff');
}/* raleway-latin-700-normal */
@font-face {
  font-family: 'Raleway';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(/astro-freelance-persona_theme/_astro/raleway-latin-700-normal.BVpQLp0x.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/raleway-latin-700-normal.JVwBSLev.woff) format('woff');
}/* roboto-latin-300-normal */
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(/astro-freelance-persona_theme/_astro/roboto-latin-300-normal.CCzlftfr.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/roboto-latin-300-normal.Dqn3NW0Y.woff) format('woff');
}/* roboto-latin-300-italic */
@font-face {
  font-family: 'Roboto';
  font-style: italic;
  font-display: swap;
  font-weight: 300;
  src: url(/astro-freelance-persona_theme/_astro/roboto-latin-300-italic.zCpkrxSM.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/roboto-latin-300-italic.0S4OQXq7.woff) format('woff');
}/* roboto-latin-400-normal */
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/astro-freelance-persona_theme/_astro/roboto-latin-400-normal.BqEyEoaF.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/roboto-latin-400-normal.D27F5sTu.woff) format('woff');
}/* roboto-latin-400-italic */
@font-face {
  font-family: 'Roboto';
  font-style: italic;
  font-display: swap;
  font-weight: 400;
  src: url(/astro-freelance-persona_theme/_astro/roboto-latin-400-italic.CSuqwwKr.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/roboto-latin-400-italic.BpsFK_tr.woff) format('woff');
}/* roboto-latin-500-normal */
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(/astro-freelance-persona_theme/_astro/roboto-latin-500-normal.7RbcRiD8.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/roboto-latin-500-normal.fsTFPL3E.woff) format('woff');
}/* roboto-latin-500-italic */
@font-face {
  font-family: 'Roboto';
  font-style: italic;
  font-display: swap;
  font-weight: 500;
  src: url(/astro-freelance-persona_theme/_astro/roboto-latin-500-italic.DOe3GFcv.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/roboto-latin-500-italic.DYW_i9qW.woff) format('woff');
}/* roboto-latin-700-normal */
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(/astro-freelance-persona_theme/_astro/roboto-latin-700-normal.BZpUvMxY.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/roboto-latin-700-normal.YuyVweIx.woff) format('woff');
}/* roboto-latin-700-italic */
@font-face {
  font-family: 'Roboto';
  font-style: italic;
  font-display: swap;
  font-weight: 700;
  src: url(/astro-freelance-persona_theme/_astro/roboto-latin-700-italic.Cb9agdGy.woff2) format('woff2'), url(/astro-freelance-persona_theme/_astro/roboto-latin-700-italic.DyccbiE3.woff) format('woff');
}