/* ==========================================================================
   Nav dock — floating bottom bar, notch FAB, quick-add fan, add dialog,
   avatar menu. Loaded AFTER layout.css. Dock is mobile-only; desktop keeps
   the top navigation (.top-nav). All rules are RTL/LTR safe.
   ========================================================================== */

/* ---------- desktop top nav (hidden on mobile) ---------- */
.top-nav {
    display: none;
    align-items: center;
    gap: 1.25rem;
}
.top-nav a {
    color: inherit;
    text-decoration: none;
    font-weight: 600;
    font-size: .92rem;
    opacity: .75;
    transition: opacity .15s ease;
}
.top-nav a:hover,
.top-nav a.active {
    opacity: 1;
}
@media (min-width: 900px) {
    .top-nav { display: flex; }
}

/* ---------- topbar adjustments for the new header ---------- */
/* layout.css wraps the topbar on small screens for the old .main-nav;
   the new header is brand + avatar only, so never wrap. */
@media (max-width: 640px) {
    .topbar { flex-wrap: nowrap; }
}

/* ---------- avatar button + menu (all viewports) ---------- */
.avatar-wrap {
    position: relative;
    margin-inline-start: auto;
}

.avatar-btn {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 2px solid var(--surface);
    background: var(--primary);
    color: var(--on-primary);
    font: inherit;
    font-weight: 700;
    display: grid;
    place-items: center;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(41, 41, 39, .15);
    padding: 0;
}
.avatar-btn svg { width: 18px; height: 18px; }

/* menu lives at body level and is position:fixed so the topbar's
   backdrop-filter stacking context can never clip or bury it */
.avatar-menu {
    position: fixed;
    top: 68px;
    inset-inline-end: 12px;
    min-width: 200px;
    background: var(--surface);
    border-radius: 16px;
    box-shadow: 0 14px 40px rgba(41, 41, 39, .18);
    padding: 6px;
    opacity: 0;
    transform: translateY(-6px) scale(.97);
    pointer-events: none;
    transition: opacity .18s ease, transform .18s ease;
    z-index: 1200;
}
.avatar-menu.open { opacity: 1; transform: none; pointer-events: auto; }
.avatar-menu a,
.avatar-menu button {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 11px 12px;
    border: 0;
    background: none;
    border-radius: 11px;
    font: inherit;
    font-size: .9rem;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
    text-align: start;
}
.avatar-menu a:hover,
.avatar-menu button:hover { background: var(--surface-2); }
.avatar-menu .danger { color: var(--danger); }
.avatar-menu svg { width: 17px; height: 17px; flex-shrink: 0; }

/* ---------- scrim ---------- */
.nav-scrim {
    position: fixed;
    inset: 0;
    background: var(--scrim);
    opacity: 0;
    pointer-events: none;
    transition: opacity .22s ease;
    z-index: 900;
}
.nav-scrim.show { opacity: 1; pointer-events: auto; }

/* ---------- bottom dock ---------- */
.page-bottom-space { height: 120px; }

.nav-dock {
    position: fixed;
    left: 0;
    right: 0;
    bottom: max(12px, env(safe-area-inset-bottom));
    padding-inline: 14px;
    z-index: 950;
    filter: drop-shadow(0 -6px 28px rgba(41, 41, 39, .14));
}
/* The bar is a transparent layout box; its visible surface is a ::before
   layer. The notch mask lives on that layer, not on .nav-bar itself, so the
   mask can never touch the nav items — masking the bar directly clipped the
   raised bubble, and forcing it through with mask-clip: no-clip left a
   hairline seam across the bubble at the bar's top edge, where the masked
   layer was composited. Separating surface from contents removes the whole
   problem instead of fighting it. */
.nav-bar {
    position: relative;
    height: 66px;
    max-width: 480px;
    margin-inline: auto;
    border-radius: 28px;
    display: flex;
    align-items: stretch;
    justify-content: space-between;
    padding-inline: 8px;
}
.nav-bar::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    background: var(--surface);
    /* notch for the FAB: circle centred on the bar's top edge */
    --nav-notch: radial-gradient(circle 42px at 50% 0, transparent 41px, #000 42px);
    -webkit-mask-image: var(--nav-notch);
    mask-image: var(--nav-notch);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
}
.nav-side { display: flex; flex: 1; position: relative; z-index: 1; }
.nav-gap { width: 84px; flex-shrink: 0; }
.nav-item {
    position: relative;
    z-index: 1;
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    color: var(--muted);
    text-decoration: none;
    font-size: .66rem;
    font-weight: 700;
    border-radius: 18px;
    transition: color .18s ease;
}
.nav-item svg { width: 21px; height: 21px; }
/* Organize icon: the slider knobs are punch-outs, so they must match the
   dock surface, not pure white. */
.nav-item svg circle[fill] { fill: var(--surface); }

/* ---------- active item: raised olive bubble ----------
   The bubble is a ::before so no markup changes. It sits behind the icon
   and lifts 15px above the bar so it visibly breaks the dock edge, the
   same language as the FAB in its notch. Colour changes independently of
   the lift, so the active state still reads even if the raise fails to paint.

   Motion note: these are real page navigations, so a CSS *transition* on
   .active would never fire — the next document renders with .active already
   set and there is no state change to interpolate. The entry is therefore a
   keyframe animation, which does run on first paint. Transitions are kept
   as the exit path for the tab that loses .active (SPA-style toggling) and
   for press feedback. */
.nav-item::before {
    content: "";
    position: absolute;
    top: -12px;
    /* inset-inline + auto margins centre the bubble in both RTL and LTR and
       leave `transform` free for the pop-in. */
    inset-inline: 0;
    /* deliberately smaller and lifted less than the 62px FAB: the FAB is the
       primary action, this is only a location indicator. Same size and lift
       would make two olive circles compete on one bar. */
    width: 40px;
    height: 40px;
    margin-inline: auto;
    border-radius: 50%;
    background: var(--primary);
    box-shadow: 0 4px 10px rgba(105, 108, 86, .28);
    transform: translateY(10px) scale(.5);
    transform-origin: 50% 80%;
    opacity: 0;
    /* exit only */
    transition: transform .24s ease-in, opacity .18s ease-in;
}
/* icon and label ride above the bubble */
.nav-item svg,
.nav-item span {
    position: relative;
    z-index: 1;
}
.nav-item svg {
    transition: transform .24s ease-in, color .2s ease;
}
.nav-item span {
    transition: transform .24s ease-in;
}

.nav-item.active { color: var(--primary-strong); }

/* The three pieces are staggered so the bubble leads, the icon rides up
   just behind it and the label settles last — one gesture instead of three
   things snapping at once. Overshoot is mild (1.24, not 1.4): a hard spring
   on a 40px circle reads as a glitch rather than as weight. */
.nav-item.active::before {
    transform: none;
    opacity: 1;
    animation: nav-bubble-in .46s cubic-bezier(.33, 1.24, .45, 1) both;
}
.nav-item.active svg {
    color: var(--on-primary);
    transform: translateY(-15px);
    animation: nav-icon-lift .44s cubic-bezier(.33, 1.24, .45, 1) 50ms both;
}
/* knobs now sit on olive, not on the dock surface */
.nav-item.active svg circle[fill] { fill: var(--primary); }
.nav-item.active span {
    transform: translateY(-4px);
    animation: nav-label-settle .38s cubic-bezier(.33, 1.18, .48, 1) 90ms both;
}

@keyframes nav-bubble-in {
    from { transform: translateY(12px) scale(.5); opacity: 0; }
    60%  { opacity: 1; }
    to   { transform: translateY(0) scale(1); opacity: 1; }
}
@keyframes nav-icon-lift {
    from { transform: translateY(0); }
    to   { transform: translateY(-15px); }
}
@keyframes nav-label-settle {
    from { transform: translateY(0); }
    to   { transform: translateY(-4px); }
}

/* Press feedback: the tap has to acknowledge itself immediately, because
   the page it navigates to takes longer to arrive than any animation. */
.nav-item:not(.active):active svg { transform: scale(.86); transition-duration: .08s; }
.nav-item:not(.active):active::before {
    transform: translateY(6px) scale(.7);
    opacity: .28;
    transition-duration: .12s;
}

@media (prefers-reduced-motion: reduce) {
    .nav-item::before,
    .nav-item svg,
    .nav-item span { transition: none; }
    .nav-item.active::before,
    .nav-item.active svg,
    .nav-item.active span { animation: none; }
}

/* ---------- FAB (seated in notch: half in, half out) ---------- */
.fab-wrap {
    position: absolute;
    left: 50%;
    top: 0;
    transform: translate(-50%, -50%);
    transition: transform .26s cubic-bezier(.34, 1.4, .5, 1);
    z-index: 952;
}
.nav-dock.open .fab-wrap { transform: translate(-50%, -62%); }
.nav-fab {
    width: 62px;
    height: 62px;
    border-radius: 50%;
    border: 0;
    cursor: pointer;
    background: var(--primary);
    color: var(--on-primary);
    display: grid;
    place-items: center;
    box-shadow: 0 8px 20px rgba(105, 108, 86, .38);
    transition: background .2s ease, transform .15s ease;
    padding: 0;
}
.nav-fab:active { transform: scale(.93); }
.nav-dock.open .nav-fab { background: var(--primary-strong); }
.nav-fab svg {
    width: 26px;
    height: 26px;
    transition: transform .28s cubic-bezier(.34, 1.4, .5, 1);
}
.nav-dock.open .nav-fab svg { transform: rotate(225deg); }

/* ---------- fan satellites ---------- */
.nav-sat {
    position: absolute;
    left: 50%;
    top: 0;
    z-index: 951;
    transform: translate(-50%, -50%) scale(0);
    transition: transform .3s cubic-bezier(.34, 1.5, .5, 1);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    border: 0;
    background: none;
    cursor: pointer;
    font: inherit;
    padding: 0;
}
.sat-1 { --dx: 74px;  --dy: -86px; }
.sat-2 { --dx: 0px;   --dy: -116px; }
.sat-3 { --dx: -74px; --dy: -86px; }
[dir="ltr"] .sat-1 { --dx: -74px; }
[dir="ltr"] .sat-3 { --dx: 74px; }
.nav-dock.open .nav-sat {
    transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1);
}
.nav-dock.open .sat-1 { transition-delay: .05s; }
.nav-dock.open .sat-2 { transition-delay: .10s; }
.nav-dock.open .sat-3 { transition-delay: .15s; }
.nav-sat .sat-dot {
    width: 50px;
    height: 50px;
    border-radius: 50%;
    background: var(--surface);
    color: var(--primary-strong);
    display: grid;
    place-items: center;
    box-shadow: 0 6px 18px rgba(41, 41, 39, .18);
}
.nav-sat .sat-dot svg { width: 21px; height: 21px; }
.nav-sat .sat-lbl {
    font-size: .68rem;
    font-weight: 700;
    background: var(--surface);
    padding: 3px 10px;
    border-radius: 999px;
    box-shadow: 0 3px 10px rgba(41, 41, 39, .12);
    white-space: nowrap;
}

/* ---------- add dialog (one component, three modes) ---------- */
.add-dialog {
    position: fixed;
    left: 12px;
    right: 12px;
    bottom: max(12px, env(safe-area-inset-bottom));
    max-width: 480px;
    margin-inline: auto;
    background: var(--surface);
    border-radius: 24px;
    padding: 18px;
    box-shadow: 0 20px 60px rgba(41, 41, 39, .25);
    transform: translateY(115%);
    transition: transform .3s cubic-bezier(.3, 1.1, .4, 1);
    z-index: 1000;
}
.add-dialog.show { transform: none; }
.add-dialog .hidden { display: none !important; }
.add-dialog-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 14px;
}
.add-dialog-title {
    font-size: 1rem;
    font-weight: 800;
    display: flex;
    align-items: center;
    gap: 8px;
}
.tag-adhoc {
    font-size: .66rem;
    font-weight: 700;
    background: var(--accent-soft);
    color: var(--accent);
    padding: 3px 9px;
    border-radius: 999px;
}
.add-dialog-close {
    border: 0;
    background: var(--surface-2);
    width: 30px;
    height: 30px;
    border-radius: 50%;
    cursor: pointer;
    color: var(--muted);
    font-size: .9rem;
}
.add-field { margin-bottom: 12px; }
.add-bulk-hint {
    margin: 6px 2px 0;
    font-size: .78rem;
    color: var(--muted);
}
.add-field input[type="text"],
.add-field input[type="number"],
.add-field textarea {
    width: 100%;
    border: 1.5px solid var(--border-strong);
    border-radius: 14px;
    padding: 12px 14px;
    font: inherit;
    font-size: .95rem;
    outline: none;
}
.add-field textarea {
    display: block;
    resize: none;
    overflow-y: auto;
    max-height: 8.5rem;
    line-height: 1.45;
}
.add-field input[type="text"]:focus,
.add-field input[type="number"]:focus,
.add-field textarea:focus { border-color: var(--primary); box-shadow: var(--focus-ring); }
.add-cats { display: flex; flex-wrap: wrap; gap: 7px; }
.add-cat {
    border: 1.5px solid var(--border-strong);
    background: var(--surface);
    border-radius: 999px;
    padding: 7px 13px;
    font: inherit;
    font-size: .78rem;
    font-weight: 600;
    cursor: pointer;
    color: var(--muted);
}
.add-cat.sel {
    border-color: var(--primary);
    color: var(--primary-strong);
    background: var(--primary-soft);
}
.add-photo-btn {
    display: flex;
    align-items: center;
    gap: 9px;
    border: 1.5px dashed var(--border-strong);
    background: var(--surface-2);
    border-radius: 14px;
    padding: 11px 14px;
    width: 100%;
    font: inherit;
    font-size: .85rem;
    font-weight: 600;
    color: var(--muted);
    cursor: pointer;
}
.add-photo-btn svg { width: 19px; height: 19px; }
#addPhotoContent { display: flex; align-items: center; gap: 9px; }
.add-photo-preview { width: 46px; height: 46px; border-radius: 10px; object-fit: cover; }
.add-submit {
    width: 100%;
    border: 0;
    border-radius: 14px;
    padding: 13px;
    background: var(--primary);
    color: var(--on-primary);
    font: inherit;
    font-size: .95rem;
    font-weight: 800;
    cursor: pointer;
    margin-top: 4px;
}
.add-submit:active { background: var(--primary-strong); }
.add-submit[disabled] {
    background: var(--disabled-bg);
    color: var(--disabled-text);
    pointer-events: none;
}

/* focus-visible for every dock/dialog control */
.avatar-btn:focus-visible,
.nav-item:focus-visible,
.nav-fab:focus-visible,
.nav-sat:focus-visible,
.add-cat:focus-visible,
.add-submit:focus-visible,
.add-photo-btn:focus-visible,
.add-dialog-close:focus-visible {
    outline: 2px solid var(--primary-strong);
    outline-offset: 2px;
    box-shadow: var(--focus-ring);
}


/* ---------- toast ---------- */
.add-toast {
    position: fixed;
    left: 50%;
    bottom: 108px;
    transform: translate(-50%, 20px);
    background: var(--text);
    color: var(--on-primary);
    font-size: .82rem;
    font-weight: 700;
    padding: 10px 18px;
    border-radius: 999px;
    opacity: 0;
    transition: opacity .25s ease, transform .25s ease;
    z-index: 1100;
    pointer-events: none;
    white-space: nowrap;
}
.add-toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ---------- item photo thumb (pantry + shopping rows) ----------
   lives here temporarily — move to pantry.css / shopping.css in the cleanup pass */
.item-thumb {
    width: 34px;
    height: 34px;
    border-radius: 10px;
    object-fit: cover;
    flex-shrink: 0;
}

/* ---------- desktop: hide mobile chrome ---------- */
@media (min-width: 900px) {
    .nav-dock,
    .nav-scrim,
    .page-bottom-space { display: none; }
    .add-toast { bottom: 32px; }
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
    .fab-wrap,
    .nav-fab svg,
    .nav-sat,
    .add-dialog,
    .nav-scrim,
    .add-toast,
    .avatar-menu { transition: none; }
}
