/* Theme layer — colors, backgrounds, borders, shadows only */
@layer theme {
  nav.sidebar {
    /* Green accent tokens — kept as local props so the theme layer owns all colors. */
    --nav-accent: light-dark(oklch(55% 0.17 155), oklch(72% 0.18 155));
    --nav-accent-soft: light-dark(
      oklch(from var(--nav-accent) l c h / 0.12),
      oklch(from var(--nav-accent) l c h / 0.18)
    );
    --nav-accent-glow: oklch(from var(--nav-accent) l c h / 0.6);

    background: var(--surface-sunken);
    color: var(--text-secondary);
    border-inline-end: 1px solid var(--border-color);

    /* Drop shadow while expanded — reinforces that the panel floats over content. */
    &[data-expanded='true'] {
      box-shadow: 4px 0 24px light-dark(oklch(0% 0 0 / 0.08), oklch(0% 0 0 / 0.4));
    }

    /* All collapse/expand transitions live in @layer theme so they outrank
       base.css's universal `* { transition-property: ... }` rule which is
       also in theme. Components-layer transitions on the same elements get
       clobbered wholesale by the universal rule.

       The trick that avoids the icon-snap problem: labels animate
       `inline-size: auto ↔ 0` instead of toggling `display`. The label
       stays in the flex layout the whole time, sized 0 in collapsed state,
       so flex slack is gradual and the icon never snaps sideways at the
       end of the animation. `interpolate-size: allow-keywords` (set in the
       components layer below) is what unlocks `auto ↔ 0`. */

    /* Sidebar's own width animation. */
    transition: inline-size var(--time-medium) var(--ease-out);

    /* Labels collapse from natural width to zero. overflow:hidden on the
       link clips the text as the label shrinks; opacity makes the fade
       look intentional rather than just a horizontal squeeze. */
    .brand-name,
    .sidebar-section summary .section-label,
    .sidebar-section a .nav-label,
    .sidebar-footer a .nav-label,
    .sidebar-footer .theme-toggle .nav-label,
    .sidebar-integrations .integrations-header > span,
    .sidebar-integrations .integration-name,
    .sidebar-integrations .integration-time {
      inline-size: auto;
      opacity: 1;
      transition:
        inline-size var(--time-medium) var(--ease-out),
        opacity var(--time-medium) var(--ease-out);
    }

    /* Theme toggle label is special: its text content swaps between
       "Light mode" and "Dark mode" on click, which would otherwise
       cause the inline-size: auto value to re-resolve and the auto↔auto
       transition (enabled by interpolate-size: allow-keywords on the
       sidebar) would animate that re-resolve over 300ms, visible as a
       text flicker. Pinning a fixed width that fits both labels stops
       the auto recalculation and the flicker with it. */
    .sidebar-footer .theme-toggle .theme-label {
      inline-size: 5.5rem;
    }

    /* Section chevron rotates when its <details> closes AND fades when
       the sidebar collapses — both transitions in one declaration. */
    .sidebar-section summary .section-chevron {
      opacity: 1;
      transition:
        transform var(--time-fast) var(--ease-standard),
        opacity var(--time-medium) var(--ease-out);
    }

    /* Drift the icons toward the rail centerline as the sidebar collapses.
       The icon's horizontal position is driven entirely by the link's
       padding-inline-start, so animating that property slides the icon
       from its expanded left-aligned position into the center of the
       collapsed rail with no terminal layout snap. The label and sidebar
       width animate in lockstep, so the whole transition reads as one
       coordinated morph. */
    .sidebar-section a,
    .sidebar-footer a,
    .sidebar-footer .theme-toggle {
      transition:
        background var(--time-fast) var(--ease-standard),
        color var(--time-fast) var(--ease-standard),
        padding-inline-start var(--time-medium) var(--ease-out);
    }

    /* Brand row padding shrinks alongside the rail width. The .brand link's
       gap, the collapse button's inline-size, and the button's opacity all
       animate so the brand-mark drifts smoothly toward the rail center as
       the rail collapses, with no discrete property snaps. */
    .sidebar-brand {
      transition: padding var(--time-medium) var(--ease-out);

      .brand {
        transition: gap var(--time-medium) var(--ease-out);
      }

      .collapse-btn {
        transition:
          inline-size var(--time-medium) var(--ease-out),
          opacity var(--time-medium) var(--ease-out),
          background var(--time-fast) var(--ease-standard),
          color var(--time-fast) var(--ease-standard);
      }
    }

    /* Same trick for the integrations card so its header icon and the
       Greenhouse status dot end up centered in the collapsed rail. */
    .sidebar-integrations .integrations-header,
    .sidebar-integrations .integration-item {
      transition:
        padding-inline-start var(--time-medium) var(--ease-out),
        margin var(--time-medium) var(--ease-out);
    }

    /* Collapsed-state targets. Same layer as the baseline rules above so
       the cascade resolves predictably. */
    &[data-expanded='false'] {
      .brand-name,
      .sidebar-section summary .section-label,
      .sidebar-section a .nav-label,
      .sidebar-footer a .nav-label,
      .sidebar-footer .theme-toggle .nav-label,
      .sidebar-integrations .integrations-header > span,
      .sidebar-integrations .integration-name,
      .sidebar-integrations .integration-time {
        inline-size: 0;
        opacity: 0;
      }

      .sidebar-section summary .section-chevron {
        opacity: 0;
      }

      /* Center icons in the rail. Math:
           link content area = rail - 2*section_pad - 2*link_pad
           padding_l_centered = (rail - 2*section_pad - icon_width) / 2
         The same shape works for the integrations card components, just
         with the card's own margin/padding factored in. */
      .sidebar-section a,
      .sidebar-footer a,
      .sidebar-footer .theme-toggle {
        padding-inline-start: calc((var(--nav-width-collapsed) - 2 * var(--space-sm) - 1.1rem) / 2);
      }

      .sidebar-integrations .integrations-header {
        padding-inline-start: calc(
          (var(--nav-width-collapsed) - 2 * var(--space-2xs) - 2 * var(--space-xs) - 1.1rem) / 2
        );
      }

      .sidebar-integrations .integration-item {
        padding-inline-start: calc(
          (var(--nav-width-collapsed) - 2 * var(--space-2xs) - 2 * var(--space-xs) - 0.5rem) / 2
        );
      }

      /* Visual separator between sections in the collapsed rail — the
         section labels are at width 0 so the four icon groups would
         otherwise blur into one continuous column. */
      .sidebar-section {
        border-block-end: 1px solid var(--border-color);
      }
    }

    .sidebar-brand {
      border-block-end: 1px solid var(--border-color);

      .brand {
        color: var(--text-primary);
      }

      .brand-mark {
        background: linear-gradient(135deg, oklch(70% 0.17 150), oklch(58% 0.18 160));
        color: oklch(100% 0 0);
      }

      .collapse-btn {
        color: var(--text-secondary);

        &:hover {
          background: var(--surface-base);
          color: var(--text-primary);
        }
      }
    }

    .sidebar-section {
      summary {
        color: var(--text-secondary);
      }

      a {
        color: var(--text-secondary);

        &:hover {
          background: var(--surface-base);
          color: var(--text-primary);
        }

        &[aria-current='page'] {
          background: var(--nav-accent-soft);
          color: var(--nav-accent);
        }

        .nav-dot {
          background: var(--nav-accent);
          box-shadow: 0 0 6px var(--nav-accent-glow);
        }
      }
    }

    .sidebar-integrations {
      background: var(--surface-deep);
      border: 1px solid var(--border-color);

      .integrations-header {
        color: var(--text-secondary);
      }

      .integration-item {
        color: var(--text-primary);
      }

      .integration-time {
        color: var(--text-secondary);
      }

      .status-dot {
        background: var(--nav-accent);
        box-shadow: 0 0 6px var(--nav-accent-glow);
      }
    }

    .sidebar-footer {
      border-block-start: 1px solid var(--border-color);

      a,
      .theme-toggle {
        color: var(--text-secondary);

        &:hover {
          background: var(--surface-base);
          color: var(--text-primary);
        }
      }

      /* Sun/moon icon crossfade. Both <g> elements live inside the same
         SVG with the same viewBox, so they overlap naturally — only the
         opacity/transform needs to flip on theme change. Same pattern
         as base.css's existing landing-page theme button; page-level
         theme tokens (--text-*, --surface-*) auto-switch via light-dark()
         so nothing else needs an explicit attribute selector. */
      .theme-toggle .theme-icon {
        .icon-sun,
        .icon-moon {
          transform-origin: center;
          transition:
            opacity var(--time-medium) var(--ease-out),
            transform var(--time-medium) var(--ease-out);
        }

        /* Dark mode is the default — moon hidden, rotated/scaled down. */
        .icon-moon {
          opacity: 0;
          transform: rotate(-45deg) scale(0.6);
        }
      }
    }

    /* Light-mode swap. `&` resolves to `nav.sidebar`, so the full selector
       becomes `html[data-theme='light'] nav.sidebar .sidebar-footer ...`.
       Nesting the rule inside nav.sidebar (rather than at @layer scope)
       lets it stay alongside its dark-mode counterpart above. */
    html[data-theme='light'] & .sidebar-footer .theme-toggle .theme-icon {
      .icon-sun {
        opacity: 0;
        transform: rotate(45deg) scale(0.6);
      }

      .icon-moon {
        opacity: 1;
        transform: rotate(0) scale(1);
      }
    }
  }
}

/* Components layer — layout, sizing, spacing only */
@layer components {
  :root {
    --nav-width: 16rem;
    --nav-width-collapsed: 4.25rem;
  }

  /* Reserve the collapsed-width rail always; the expanded sidebar floats over
     the content thanks to its z-index, so layout doesn't shift on toggle. */
  nav.sidebar ~ * {
    padding-inline-start: var(--nav-width-collapsed);
  }

  nav.sidebar {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    inline-size: var(--nav-width);
    display: flex;
    flex-direction: column;
    z-index: 50;
    overflow: hidden;

    /* Enable keyword interpolation so:
       - .sidebar-section ::details-content can transition block-size 0 ↔ auto
       - labels can transition inline-size auto ↔ 0 (the icon-snap fix)
       Scoped to the sidebar to avoid accidental side effects elsewhere. */
    interpolate-size: allow-keywords;

    /* Lucide-style strokes for every inline SVG in the sidebar. flex:none
       prevents flex layouts from shrinking SVGs that have explicit
       width/height attributes (like the theme-toggle button's sun/moon
       icon) below their intended inline-size. */
    svg {
      flex: none;
      inline-size: 1.1rem;
      block-size: 1.1rem;
      fill: none;
      stroke: currentColor;
      stroke-width: 2;
      stroke-linecap: round;
      stroke-linejoin: round;
    }

    /* ---- Brand / collapse header ---- */
    .sidebar-brand {
      display: flex;
      align-items: center;
      /* flex-start + margin-inline-start: auto on the collapse button is
         equivalent to justify-content: space-between, but lets us animate
         padding-inline-start without fighting a discrete justify-content
         flip when collapsed. position: relative establishes a containing
         block so the collapse button can be moved out of the flex flow
         in collapsed state via absolute positioning. */
      position: relative;
      gap: var(--space-sm);
      padding: var(--space-md) var(--space-base);
      min-block-size: calc(var(--space-3xl) + var(--space-md));

      .brand {
        display: flex;
        align-items: center;
        gap: var(--space-sm);
        text-decoration: none;
        font-weight: var(--fw-semibold);
        font-size: var(--fs-medium);
        overflow: hidden;
      }

      .brand-mark {
        position: relative;
        flex: none;
        display: grid;
        place-items: center;
        inline-size: var(--space-2xl);
        block-size: var(--space-2xl);
        border-radius: var(--radius-md);

        svg {
          inline-size: 1.15rem;
          block-size: 1.15rem;
          stroke-width: 1.8;
        }

        /* Chevron-right indicator that appears at the bottom-right of the
           brand-mark when the sidebar is collapsed, signaling that
           clicking it expands the sidebar. Hidden in expanded state.

           SVG colors via mask-image instead of background-image so the
           chevron inherits the page's --text-primary token (which flips
           via light-dark()), keeping the indicator legible in both
           themes without an explicit dark-mode override. */
        &::after {
          content: '';
          position: absolute;
          inset-block-end: -4px;
          inset-inline-end: -4px;
          inline-size: 18px;
          block-size: 18px;
          border-radius: 50%;
          background-color: var(--surface-base);
          border: 1px solid var(--border-color);
          opacity: 0;
          transition: opacity var(--time-medium) var(--ease-out);
          pointer-events: none;
        }

        &::before {
          content: '';
          position: absolute;
          inset-block-end: -4px;
          inset-inline-end: -4px;
          inline-size: 18px;
          block-size: 18px;
          background-color: var(--text-primary);
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E");
          mask-size: 70%;
          mask-position: center;
          mask-repeat: no-repeat;
          opacity: 0;
          transition: opacity var(--time-medium) var(--ease-out);
          pointer-events: none;
          /* Layer above ::after so the chevron sits on top of the badge. */
          z-index: 1;
        }
      }

      .brand-name {
        white-space: nowrap;
      }

      .collapse-btn {
        flex: none;
        display: grid;
        place-items: center;
        /* margin-inline-start: auto pushes the button to the row's end,
           replacing justify-content: space-between with a per-property
           equivalent that doesn't snap when the brand row's padding
           animates. */
        margin-inline-start: auto;
        inline-size: var(--space-xl);
        block-size: var(--space-xl);
        padding: 0;
        background: transparent;
        border: 1px solid transparent;
        border-radius: var(--radius-sm);
        cursor: pointer;
        transition:
          background var(--time-fast) var(--ease-standard),
          color var(--time-fast) var(--ease-standard);

        svg {
          inline-size: 1rem;
          block-size: 1rem;
          transition: transform var(--time-medium) var(--ease-out);
        }
      }
    }

    /* ---- Scrollable middle ---- */
    .sidebar-scroll {
      flex: 1 1 auto;
      overflow-y: auto;
      overflow-x: hidden;
      padding-block: var(--space-sm);
      scrollbar-width: thin;
    }

    /* ---- Collapsible sections ---- */
    .sidebar-section {
      padding-inline: var(--space-sm);

      & + .sidebar-section {
        margin-block-start: var(--space-xs);
      }

      /* Smoothly animate open/close via the new ::details-content pseudo.
         content-visibility has to ride along with allow-discrete so the
         show/hide flip waits for the block-size transition. */
      &::details-content {
        block-size: 0;
        overflow: clip;
        transition:
          block-size var(--time-medium) var(--ease-out),
          content-visibility var(--time-medium) var(--ease-out) allow-discrete;
      }

      &[open]::details-content {
        block-size: auto;
      }

      summary {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-sm);
        padding: var(--space-sm) var(--space-sm) var(--space-2xs);
        font-size: var(--fs-tiny);
        font-weight: var(--fw-semibold);
        letter-spacing: 0.1em;
        text-transform: uppercase;
        cursor: pointer;
        list-style: none;
        user-select: none;

        &::-webkit-details-marker {
          display: none;
        }

        .section-chevron {
          inline-size: 0.95rem;
          block-size: 0.95rem;
          /* transition lives in @layer theme so it can override base.css's
             universal transition-property rule. */
        }
      }

      &:not([open]) summary .section-chevron {
        transform: rotate(-90deg);
      }

      ul {
        list-style: none;
        padding: 0;
        margin: 0;
        display: flex;
        flex-direction: column;
        gap: var(--space-3xs);
      }

      li + li {
        margin-block-start: 0;
      }

      a {
        position: relative;
        display: flex;
        align-items: center;
        gap: var(--space-sm);
        padding: var(--space-xs) var(--space-sm);
        border-radius: var(--radius-md);
        text-decoration: none;
        font-size: var(--fs-small);
        font-weight: var(--fw-medium);
        line-height: 1.2;
        min-block-size: calc(var(--space-xl) + var(--space-2xs));
        transition:
          background var(--time-fast) var(--ease-standard),
          color var(--time-fast) var(--ease-standard);

        .nav-label {
          /* flex: 0 1 auto so the explicit inline-size from the theme
             layer's collapse animation wins. flex: 1 (= 1 1 0%) would
             force the label to fill remaining space and prevent the
             inline-size: 0 collapse from taking effect. */
          flex: 0 1 auto;
          min-inline-size: 0;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }

        .nav-dot {
          flex: none;
          inline-size: 0.45rem;
          block-size: 0.45rem;
          border-radius: 50%;
        }

        &:not([aria-current='page']) .nav-dot {
          display: none;
        }
      }
    }

    /* ---- Integrations status card ---- */
    .sidebar-integrations {
      margin: var(--space-md) var(--space-sm) var(--space-sm);
      padding: var(--space-sm) var(--space-base);
      border-radius: var(--radius-md);

      .integrations-header {
        display: flex;
        align-items: center;
        gap: var(--space-xs);
        margin-block-end: var(--space-xs);
        font-size: var(--fs-tiny);
        font-weight: var(--fw-semibold);
        text-transform: uppercase;
        letter-spacing: 0.08em;

        svg {
          inline-size: 0.95rem;
          block-size: 0.95rem;
        }
      }

      .integration-item {
        display: flex;
        align-items: center;
        gap: var(--space-xs);
        font-size: var(--fs-xsmall);
      }

      .integration-name {
        /* See .nav-label note above — same reason. */
        flex: 0 1 auto;
        min-inline-size: 0;
        font-weight: var(--fw-medium);
      }

      .integration-time {
        font-size: var(--fs-tiny);
      }

      .status-dot {
        flex: none;
        inline-size: 0.5rem;
        block-size: 0.5rem;
        border-radius: 50%;
      }
    }

    /* ---- Footer actions ---- */
    .sidebar-footer {
      flex: none;
      padding: var(--space-sm);

      ul {
        list-style: none;
        padding: 0;
        margin: 0;
        display: flex;
        flex-direction: column;
        gap: var(--space-3xs);
      }

      li + li {
        margin-block-start: 0;
      }

      /* Both <a> footer links and the theme-toggle <button> share the same
         visual treatment so the button feels like a regular nav item. */
      a,
      .theme-toggle {
        display: flex;
        align-items: center;
        gap: var(--space-sm);
        padding: var(--space-xs) var(--space-sm);
        border-radius: var(--radius-md);
        text-decoration: none;
        font-size: var(--fs-small);
        font-weight: var(--fw-medium);
        min-block-size: calc(var(--space-xl) + var(--space-2xs));
        transition:
          background var(--time-fast) var(--ease-standard),
          color var(--time-fast) var(--ease-standard);

        .nav-label {
          /* flex: 0 1 auto so the explicit inline-size from the theme
             layer's collapse animation wins. flex: 1 (= 1 1 0%) would
             force the label to fill remaining space and prevent the
             inline-size: 0 collapse from taking effect. */
          flex: 0 1 auto;
          min-inline-size: 0;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }
      }

      /* Button reset — strip default <button> chrome so it inherits the
         link styling above instead of UA defaults. */
      .theme-toggle {
        inline-size: 100%;
        background: transparent;
        border: 0;
        font: inherit;
        cursor: pointer;
        text-align: start;
      }
    }

    /* ---- Collapsed state ---- */
    &[data-expanded='false'] {
      inline-size: var(--nav-width-collapsed);

      /* Label hiding (inline-size: 0 + opacity: 0) lives in @layer theme
         alongside the baseline rule, so it animates via the per-property
         transitions defined there. The icon stays glued to its existing
         padding-inline-start — no justify-content reflow at the end. */

      /* Brand row centering in collapsed state. The brand-mark sits at
         padding-inline-start of the row (since the .brand link has no
         left padding of its own). To center a 32px mark in the 68px rail,
         start padding = (68 - 32) / 2 = 18px. The collapse button shrinks
         to 0 inline-size + opacity, and the brand-mark itself becomes
         the click target (see index.html). A small chevron indicator
         pseudo-element on the brand-mark acts as a visible affordance. */
      .sidebar-brand {
        padding-inline-start: calc((var(--nav-width-collapsed) - var(--space-2xl)) / 2);
        padding-inline-end: 0;

        .brand {
          /* Drop the gap around the now-zero-width brand-name. */
          gap: 0;
        }

        .collapse-btn {
          inline-size: 0;
          opacity: 0;
          pointer-events: none;
        }

        /* Show the chevron indicator on the brand-mark to signal that
           clicking it expands the sidebar. ::after is the circular badge
           background; ::before is the chevron glyph layered on top. */
        .brand-mark::after,
        .brand-mark::before {
          opacity: 1;
        }
      }

      .collapse-btn svg {
        transform: rotate(180deg);
      }

      .sidebar-section summary {
        pointer-events: none;
      }

      .sidebar-section a .nav-dot {
        display: none;
      }

      .sidebar-integrations {
        /* Padding/margin still tighten up so the card visually shrinks
           with the rail; the inner items stay left-aligned so their
           icons don't snap when the labels finish collapsing. */
        margin-inline: var(--space-2xs);
        padding: var(--space-xs);

        .integrations-header {
          margin-block-end: 0;
        }
      }
    }
  }
}
