/* @context yaffo-gallery */

.photo-gallery {
    flex: 1;
}

.photo-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 15px;
}

.photo-card {
    background: var(--color-surface);
    border-radius: var(--radius-md);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
    transition: transform 0.2s, box-shadow 0.2s;
    cursor: pointer;
}

.photo-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg);
}

.photo-thumb {
    position: relative;
}

/* Heart sits above the hover-info overlay; non-favorites reveal on card hover,
   favorites stay shown so the grid reads at a glance. */
.photo-card .favorite-toggle {
    z-index: 2;
    opacity: 0;
}

.photo-card:hover .favorite-toggle,
.photo-card .favorite-toggle.is-favorite {
    opacity: 1;
}

.photo-card img {
    width: 100%;
    height: 250px;
    object-fit: cover;
    display: block;
}

/* Play badge centered over a video's poster/placeholder. A real button: clicking
   it plays the clip inline in the card (gallery_video.js) instead of navigating. */
.video-play-badge {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 56px;
    height: 56px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--color-backdrop);
    cursor: pointer;
    z-index: 1;
}

.video-play-badge:hover {
    background: var(--color-surface-inverse);
}

.video-play-badge::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 54%;
    transform: translate(-50%, -50%);
    border-style: solid;
    border-width: 11px 0 11px 18px;
    border-color: transparent transparent transparent var(--color-text-inverse);
}

/* Duration pill in the bottom-right corner of a video thumb. */
.video-duration {
    position: absolute;
    bottom: 6px;
    right: 6px;
    padding: 1px 6px;
    border-radius: 4px;
    background: var(--color-surface-inverse);
    color: var(--color-text-inverse);
    font-size: var(--font-size-xs);
    line-height: 1.4;
    font-variant-numeric: tabular-nums;
    pointer-events: none;
    z-index: 1;
}

.video-main {
    max-width: 100%;
    max-height: 100%;
}

/* Inline player that replaces the still when the play badge is clicked. Keeps the
   photo thumb's fixed 250px so the grid lines up, but letterboxes (contain, not
   cover) so the frame — and the native control bar at its bottom — fits inside the
   box instead of being cropped. */
.photo-thumb .video-inline {
    width: 100%;
    height: 250px;
    object-fit: contain;
    display: block;
    background: var(--color-surface-inverse);
    position: relative;
    z-index: 1;
}

/* The hover-info overlay is absolutely positioned, so it paints above the
   non-positioned <video> and swallows the mouse-over the native controls need to
   un-hide. Drop it while a clip is previewing. */
.photo-thumb.is-playing .photo-hover {
    display: none;
}

.photo-hover {
    position: absolute;
    inset: 0;
    margin: 0;
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    overflow-y: auto;
    background: var(--color-surface-inverse);
    color: var(--color-text-inverse);
    opacity: 0;
    transition: opacity 0.2s;
}

.photo-card:hover .photo-hover {
    opacity: 1;
}

.photo-hover-row {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.photo-hover-row dt {
    font-size: var(--font-size-xs);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    opacity: 0.65;
}

.photo-hover-row dd {
    margin: 0;
    font-size: var(--font-size-sm);
}

.photo-hover-path {
    font-family: var(--font-mono);
    word-break: break-all;
}

.photo-info {
    padding: 12px;
}

.photo-date {
    font-size: var(--font-size-sm);
    color: var(--color-text-secondary);
    margin-bottom: 5px;
}

.photo-people {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
}

.person-tag {
    font-size: var(--font-size-xs);
    padding: 3px 8px;
    background: var(--color-accent-soft);
    color: var(--color-accent);
    border-radius: var(--radius-pill);
}
/* View toggle (Grid | Timeline) in the page header */
.view-toggle {
    display: inline-flex;
    gap: 0;
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    overflow: hidden;
}

.view-toggle a {
    border: none;
    border-radius: 0;
}

.view-toggle a.is-active {
    background: var(--color-accent);
    color: var(--color-on-accent);
}

/* Timeline view: day sections with sticky headers, heavier month dividers */
.timeline-month-divider {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-heading);
    color: var(--color-text);
    margin: 30px 0 5px;
    /* Anchor target for scrubber jumps: land below the sticky navbar. */
    scroll-margin-top: calc(var(--navbar-height, 56px) + 10px);
}

.timeline-month-divider:first-child {
    margin-top: 0;
}

.timeline-section {
    margin-bottom: 25px;
}

.timeline-day-header {
    position: sticky;
    /* Below the sticky navbar, not under it: --navbar-height is measured at
       runtime by timeline_scrubber.js (themes size the navbar differently);
       the fallback covers the no-JS render. */
    top: var(--navbar-height, 56px);
    z-index: 5;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 0;
    margin: 0 0 10px;
    background: var(--color-bg);
    font-size: var(--font-size-md);
    color: var(--color-text-secondary);
}

.timeline-day-count {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    white-space: nowrap;
}

/* The date scrubber rail on the right edge */
.timeline-scrubber {
    position: fixed;
    top: calc(var(--navbar-height, 56px) + 44px);
    bottom: 40px;
    right: 6px;
    width: 44px;
    z-index: 10;
    cursor: ns-resize;
    touch-action: none;
    user-select: none;
    border-radius: var(--radius-pill);
}

.timeline-scrubber:hover,
.timeline-scrubber:active {
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
}

.timeline-scrubber-year {
    position: absolute;
    right: 0;
    width: 100%;
    transform: translateY(-50%);
    text-align: center;
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    text-decoration: none;
    padding: 2px 0;
}

.timeline-scrubber-year:hover {
    color: var(--color-text);
}

.timeline-scrubber-year.is-active {
    color: var(--color-accent);
    font-weight: var(--font-weight-heading);
}

/* The newest year's mark sits at the rail's very top (0%); centering on that
   point would push its top half outside the rail, so hang it downward instead. */
.timeline-scrubber-year:first-of-type {
    transform: translateY(0);
}

.timeline-scrubber-bubble {
    position: absolute;
    right: 100%;
    margin-right: 8px;
    transform: translateY(-50%);
    background: var(--color-surface-inverse);
    color: var(--color-text-inverse);
    font-size: var(--font-size-sm);
    padding: 4px 10px;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-md);
    white-space: nowrap;
    pointer-events: none;
}

.timeline-scrubber-bubble.is-transient {
    animation: timeline-scrubber-bubble-fade 1100ms ease-out forwards;
}

@keyframes timeline-scrubber-bubble-fade {
    0%, 70% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.timeline-scrubber-marker {
    position: absolute;
    right: -1px;
    z-index: 2;
    width: 14px;
    height: 14px;
    transform: translateY(-50%);
    background: var(--color-accent);
    border: 3px solid var(--color-bg);
    border-radius: 50%;
    box-shadow: 0 0 0 2px var(--color-accent), var(--shadow-md);
    pointer-events: none;
    transition: top 160ms ease-out;
}

@media (max-width: 900px) {
    .timeline-scrubber {
        display: none;
    }
}

/* Per-month density bars along the scrubber's time axis */
.timeline-scrubber-bar {
    position: absolute;
    right: 4px;
    min-height: 2px;
    background: var(--color-accent);
    opacity: 0.3;
    border-radius: var(--radius-pill);
    pointer-events: none;
}

.timeline-scrubber:hover .timeline-scrubber-bar {
    opacity: 0.5;
}

/* Infinite-scroll sentinel: invisible, but tall enough that "revealed" fires
   a comfortable distance before the user hits the bottom. */
.timeline-sentinel {
    height: 120px;
}
