/* ============================================================================
 * photo_social.css - Social photo layer (slice 3)
 * Standalone, namespaced .ph-*  - loaded via html_css() (NOT the gulp bundle),
 * so it is served + cache-busted independently of use_gulp.
 * Crimson design language (#d71149), mobile-first, reuses the .mb-card look.
 * ==========================================================================*/

:root {
    --ph-crimson: #d71149;
    --ph-crimson-dark: #9A1520;
    --ph-navy: #0f172a;
    --ph-ink: #1e293b;
    --ph-muted: #64748b;
    --ph-line: #e6e8ee;
    --ph-bg: #ffffff;
    --ph-radius: 14px;
    --ph-shadow: 0 2px 10px rgba(15, 23, 42, .08);
    --ph-shadow-hi: 0 8px 24px rgba(15, 23, 42, .16);
}

/* ---- section shell ---- */
.ph-section { margin: 14px 0 8px; }
.ph-section * { box-sizing: border-box; }

.ph-head {
    display: flex; align-items: center; flex-wrap: wrap;
    gap: 10px; margin-bottom: 12px;
}
.ph-head-title { font-size: 15px; font-weight: 700; color: var(--ph-ink); margin: 0; }
.ph-head-spacer { flex: 1 1 auto; }

.ph-hint {
    width: 100%; font-size: 12.5px; color: var(--ph-muted);
    margin: -2px 0 10px; line-height: 1.5;
}

/* ---- quota chip ---- */
.ph-quota {
    display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
    font-size: 12px; color: var(--ph-ink);
    background: #f7f8fb; border: 1px solid var(--ph-line);
    border-radius: 999px; padding: 5px 12px;
}
.ph-quota b { font-weight: 700; }
.ph-quota .ph-q-sep { color: var(--ph-line); }
.ph-quota .ph-q-full { color: var(--ph-crimson); font-weight: 700; }

/* ---- add button (section-scoped, never a FAB) ---- */
.ph-add-btn {
    display: inline-flex; align-items: center; gap: 8px;
    background: var(--ph-crimson); color: #fff; border: 0;
    font-size: 13.5px; font-weight: 700; cursor: pointer;
    padding: 9px 16px; border-radius: 999px;
    box-shadow: 0 2px 8px rgba(215, 17, 73, .30);
    transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
}
.ph-add-btn:hover { background: var(--ph-crimson-dark); box-shadow: 0 4px 14px rgba(215, 17, 73, .42); transform: translateY(-1px); }
.ph-add-btn:active { transform: translateY(0); }
.ph-add-btn i { font-size: 13px; }
.ph-hidden { display: none !important; }

/* ---- masonry-ish grid (no CLS: aspect box reserved) ---- */
.ph-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 8px;
}
.ph-cell {
    position: relative; width: 100%; padding-top: 100%;
    border-radius: 12px; overflow: hidden; cursor: pointer;
    background: #eef0f4; box-shadow: var(--ph-shadow);
    transition: transform .14s ease, box-shadow .14s ease;
}
.ph-cell:hover { transform: translateY(-2px) scale(1.01); box-shadow: var(--ph-shadow-hi); }
.ph-cell img {
    position: absolute; inset: 0; width: 100%; height: 100%;
    object-fit: cover; display: block;
}
.ph-cell .ph-badge {
    position: absolute; top: 6px; left: 6px;
    background: rgba(15, 23, 42, .78); color: #fff;
    font-size: 10px; font-weight: 600; padding: 2px 7px; border-radius: 999px;
}
.ph-cell .ph-cmeta {
    position: absolute; bottom: 0; left: 0; right: 0;
    display: flex; align-items: center; gap: 6px;
    padding: 14px 8px 6px; color: #fff; font-size: 11px;
    background: linear-gradient(to top, rgba(0, 0, 0, .55), transparent);
}
.ph-cell .ph-cmeta i { font-size: 10px; opacity: .9; }
.ph-cell .ph-cmeta .ph-cm-sp { flex: 1; }

/* ---- states ---- */
.ph-empty, .ph-loading {
    text-align: center; color: var(--ph-muted); font-size: 13px;
    padding: 22px 10px; border: 1px dashed var(--ph-line); border-radius: 12px;
}
/* Load failure. Solid amber border, not the empty state's dashed grey - "this broke" must
   not look like "this is empty" at a glance (that read as data loss to users). */
.ph-empty.ph-error {
    border-style: solid; border-color: #f0c36d; background: #fffaf0; color: #8a6114;
}
.ph-empty.ph-error .ph-error-msg { margin-bottom: 10px; }

.ph-more-wrap { text-align: center; margin-top: 12px; }
.ph-more-btn {
    background: #fff; border: 1px solid var(--ph-line); color: var(--ph-ink);
    font-size: 13px; font-weight: 600; padding: 8px 18px; border-radius: 999px; cursor: pointer;
}
.ph-more-btn:hover { border-color: var(--ph-crimson); color: var(--ph-crimson); }

/* ---- discovery feed (home "Foto Terbaru" + the /photos page) ---- */
.ph-feed .ph-grid { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 14px; }
.ph-feed .ph-cell {
    position: relative; padding-top: 0; height: auto; cursor: pointer;
    display: flex; flex-direction: column; background: #fff;
    border: 1px solid var(--ph-line); border-radius: 12px; overflow: hidden;
    box-shadow: var(--ph-shadow);
}
.ph-feed .ph-cell:hover { transform: translateY(-3px); box-shadow: var(--ph-shadow-hi); }
.ph-feed .ph-cell-img { position: relative; width: 100%; padding-top: 72%; overflow: hidden; background: #eef0f4; }
.ph-feed .ph-cell-img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.ph-feed .ph-cap {
    display: flex; align-items: center; gap: 7px; padding: 9px 11px 5px;
    font-size: 12.5px; min-width: 0;
}
.ph-feed .ph-cap > i { color: var(--ph-crimson); font-size: 12px; flex: 0 0 auto; }
/* Caption logo(s): event/team = one crest; a match = both team crests, slightly overlapped. */
.ph-feed .ph-cap-logos { display: inline-flex; align-items: center; flex: 0 0 auto; }
.ph-feed .ph-cap-logo {
    /* position:static + inset:auto override the base ".ph-cell img { position:absolute; inset:0 }"
       masonry rule, which would otherwise pin these crests to the photo's corner. */
    position: static; inset: auto;
    width: 22px; height: 22px; object-fit: contain; border-radius: 50%;
    background: #fff; border: 1px solid var(--ph-line); padding: 1px; box-sizing: border-box; flex: 0 0 auto;
}
.ph-feed .ph-cap--match .ph-cap-logo + .ph-cap-logo { margin-left: -6px; }
.ph-feed .ph-cap-link {
    color: var(--ph-ink); font-weight: 700; text-decoration: none;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ph-feed .ph-cap-link:hover { color: var(--ph-crimson); text-decoration: underline; }
.ph-feed .ph-cmt {
    padding: 0 11px 11px; font-size: 12px; color: var(--ph-muted); line-height: 1.45;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ph-feed .ph-cmt b { color: var(--ph-ink); font-weight: 600; }

/* ============================================================================
 * Bottom-sheet + modal overlay (shared)
 * ==========================================================================*/
.ph-overlay {
    /* Above the lightbox (12500) so a sheet opened FROM the lightbox - tag picker, report -
       stacks on top and is usable, not hidden behind the image. Toast (13000) stays topmost. */
    position: fixed; inset: 0; z-index: 12600;
    background: rgba(15, 23, 42, .55);
    display: flex; align-items: flex-end; justify-content: center;
    opacity: 0; visibility: hidden; transition: opacity .18s ease;
}
.ph-overlay.ph-open { opacity: 1; visibility: visible; }

.ph-sheet {
    width: 100%; max-width: 560px; background: var(--ph-bg);
    border-radius: 18px 18px 0 0; max-height: 92vh; overflow-y: auto;
    transform: translateY(24px); transition: transform .2s ease;
    box-shadow: 0 -8px 30px rgba(0, 0, 0, .25);
    -webkit-overflow-scrolling: touch;
}
.ph-overlay.ph-open .ph-sheet { transform: translateY(0); }

.ph-sheet-head {
    position: sticky; top: 0; z-index: 2; background: var(--ph-bg);
    display: flex; align-items: center; gap: 10px;
    padding: 14px 16px; border-bottom: 1px solid var(--ph-line);
}
.ph-sheet-title { font-size: 15px; font-weight: 700; margin: 0; color: var(--ph-ink); flex: 1; }
.ph-x {
    background: #f1f3f7; border: 0; width: 30px; height: 30px; border-radius: 50%;
    font-size: 16px; line-height: 1; color: var(--ph-muted); cursor: pointer;
}
.ph-x:hover { background: #e6e8ee; color: var(--ph-ink); }
.ph-sheet-body { padding: 16px; }

.ph-sheet-foot {
    position: sticky; bottom: 0; background: var(--ph-bg);
    display: flex; gap: 10px; padding: 12px 16px;
    border-top: 1px solid var(--ph-line);
}
.ph-btn {
    flex: 1; border: 0; border-radius: 10px; font-size: 14px; font-weight: 700;
    padding: 12px 14px; cursor: pointer;
}
.ph-btn-ghost { background: #f1f3f7; color: var(--ph-ink); }
.ph-btn-ghost:hover { background: #e6e8ee; }
.ph-btn-primary { background: var(--ph-crimson); color: #fff; }
.ph-btn-primary:hover { background: var(--ph-crimson-dark); }
.ph-btn:disabled { opacity: .5; cursor: not-allowed; }

/* ---- upload sheet ---- */
.ph-upload-target {
    font-size: 13px; color: var(--ph-ink); background: #f7f8fb;
    border: 1px solid var(--ph-line); border-radius: 10px;
    padding: 10px 12px; margin-bottom: 12px;
}
.ph-upload-target b { color: var(--ph-crimson); }

.ph-quota-block { margin-bottom: 14px; }
.ph-quota-row {
    display: flex; align-items: center; justify-content: space-between;
    font-size: 13px; padding: 7px 0; border-bottom: 1px dashed var(--ph-line);
}
.ph-quota-row:last-child { border-bottom: 0; }
.ph-quota-row .ph-qr-label { color: var(--ph-muted); }
.ph-quota-row .ph-qr-val { font-weight: 700; color: var(--ph-ink); }
.ph-quota-row.ph-qr-after .ph-qr-val { color: var(--ph-crimson); }

.ph-pick {
    display: flex; flex-direction: column; align-items: center; gap: 8px;
    border: 2px dashed var(--ph-crimson); border-radius: 14px;
    padding: 22px 14px; text-align: center; cursor: pointer;
    color: var(--ph-crimson); background: rgba(215, 17, 73, .04);
    transition: background .14s ease;
}
.ph-pick:hover { background: rgba(215, 17, 73, .08); }
.ph-pick i { font-size: 26px; }
.ph-pick .ph-pick-main { font-size: 14px; font-weight: 700; }
.ph-pick .ph-pick-sub { font-size: 12px; color: var(--ph-muted); }

.ph-previews {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
    gap: 8px; margin-top: 14px;
}
.ph-pv {
    position: relative; padding-top: 100%; border-radius: 10px; overflow: hidden;
    background: #eef0f4; box-shadow: var(--ph-shadow);
}
.ph-pv img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ph-pv .ph-pv-rm {
    position: absolute; top: 4px; right: 4px; width: 22px; height: 22px; border-radius: 50%;
    background: rgba(15, 23, 42, .8); color: #fff; border: 0; font-size: 13px; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
}
.ph-pv .ph-pv-bar {
    position: absolute; left: 0; bottom: 0; height: 4px; width: 0%;
    background: var(--ph-crimson); transition: width .2s ease;
}
.ph-pv.ph-pv-done .ph-pv-bar { width: 100% !important; background: #16a34a; }
.ph-pv.ph-pv-err { outline: 2px solid var(--ph-crimson); }

.ph-selcount { font-size: 12.5px; color: var(--ph-muted); margin-top: 10px; }

.ph-atcap {
    display: flex; gap: 10px; align-items: flex-start;
    background: #fff5f7; border: 1px solid #f6c9d5; border-radius: 12px;
    padding: 12px; margin-bottom: 12px;
}
.ph-atcap i { color: var(--ph-crimson); font-size: 18px; margin-top: 1px; }
.ph-atcap .ph-atcap-t { font-weight: 700; font-size: 13.5px; color: var(--ph-crimson-dark); }
.ph-atcap .ph-atcap-h { font-size: 12.5px; color: var(--ph-ink); margin-top: 2px; }

/* ============================================================================
 * Lightbox
 * ==========================================================================*/
.ph-lb-overlay {
    position: fixed; inset: 0; z-index: 12500; background: rgba(8, 10, 18, .92);
    display: flex; opacity: 0; visibility: hidden; transition: opacity .18s ease;
    flex-direction: column;
}
.ph-lb-overlay.ph-open { opacity: 1; visibility: visible; }
.ph-lb-top {
    display: flex; align-items: center; gap: 10px; padding: 10px 14px; color: #fff;
}
.ph-lb-top .ph-lb-sp { flex: 1; }
.ph-lb-top button {
    background: rgba(255, 255, 255, .12); border: 0; color: #fff; cursor: pointer;
    width: 38px; height: 38px; border-radius: 50%; font-size: 16px;
}
.ph-lb-top button:hover { background: rgba(255, 255, 255, .24); }
.ph-lb-main {
    flex: 1; display: flex; min-height: 0;
}
.ph-lb-stage {
    flex: 1; display: flex; align-items: center; justify-content: center;
    position: relative; min-width: 0; padding: 4px;
}
.ph-lb-stage img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 6px; }
.ph-lb-nav {
    position: absolute; top: 50%; transform: translateY(-50%);
    background: rgba(255, 255, 255, .14); border: 0; color: #fff; cursor: pointer;
    width: 42px; height: 42px; border-radius: 50%; font-size: 18px;
}
.ph-lb-nav:hover { background: rgba(255, 255, 255, .28); }
.ph-lb-prev { left: 8px; }
.ph-lb-next { right: 8px; }

.ph-lb-side {
    width: 340px; max-width: 42%; background: #fff; display: flex; flex-direction: column;
    min-height: 0;
}
.ph-lb-side-scroll { flex: 1; overflow-y: auto; padding: 14px; }
.ph-lb-uploader { font-size: 12.5px; color: var(--ph-muted); }
.ph-lb-caption { font-size: 14px; color: var(--ph-ink); margin: 6px 0 12px; line-height: 1.5; }

.ph-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.ph-chip {
    display: inline-flex; align-items: center; gap: 6px;
    background: #f1f3f7; border-radius: 999px; padding: 4px 10px; font-size: 12px; color: var(--ph-ink);
}
.ph-chip .ph-chip-rm { background: none; border: 0; color: var(--ph-muted); cursor: pointer; font-size: 12px; padding: 0; }
.ph-chip .ph-chip-rm:hover { color: var(--ph-crimson); }
.ph-chip-add {
    background: none; border: 1px dashed var(--ph-crimson); color: var(--ph-crimson);
    cursor: pointer; border-radius: 999px; padding: 4px 10px; font-size: 12px; font-weight: 600;
}

.ph-lb-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.ph-lb-actions button {
    background: #f1f3f7; border: 0; color: var(--ph-ink); cursor: pointer;
    font-size: 12px; font-weight: 600; padding: 7px 12px; border-radius: 8px;
    display: inline-flex; align-items: center; gap: 6px;
}
.ph-lb-actions button:hover { background: #e6e8ee; }
.ph-lb-actions .ph-danger { color: var(--ph-crimson); }

/* Share popup (photo lightbox) — self-contained, same look as the site-wide FsShare widget.
   Above the lightbox overlay (which sits ~12500). */
.ph-share-ov {
    position: fixed; inset: 0; z-index: 13000; display: flex; align-items: center; justify-content: center;
    background: rgba(8, 11, 18, .55); padding: 16px; opacity: 0; transition: opacity .18s ease;
    -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.ph-share-ov.ph-show { opacity: 1; }
.ph-share-panel {
    background: #fff; border-radius: 18px; width: 100%; max-width: 470px; padding: 22px 22px 20px;
    box-shadow: 0 18px 60px rgba(0, 0, 0, .35);
    transform: translateY(8px) scale(.98); transition: transform .18s ease;
}
.ph-share-ov.ph-show .ph-share-panel { transform: none; }
.ph-share-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 18px; }
.ph-share-head span { font-size: 19px; font-weight: 800; color: #101623; }
.ph-share-x { background: #f1f3f7; border: 0; width: 34px; height: 34px; border-radius: 50%; font-size: 20px; line-height: 1; color: #64748b; cursor: pointer; }
.ph-share-x:hover { background: #e6e8ee; }
.ph-share-grid { display: flex; flex-wrap: wrap; gap: 6px 4px; justify-content: center; margin-bottom: 16px; }
.ph-share-item { flex: 1 1 72px; max-width: 88px; display: flex; flex-direction: column; align-items: center; gap: 7px; text-decoration: none; padding: 4px 2px; }
.ph-share-ic { width: 52px; height: 52px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 22px; transition: transform .12s ease; }
.ph-share-item:hover .ph-share-ic { transform: translateY(-2px) scale(1.05); }
.ph-share-lbl { font-size: 12px; font-weight: 600; color: #334155; }
.ph-share-copy { width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; background: #f4f6fa; border: 1px solid #e6e9f0; border-radius: 12px; padding: 13px; font-size: 14px; font-weight: 700; color: #101623; cursor: pointer; }
.ph-share-copy:hover { background: #eef1f6; }
.ph-share-copy.ph-copied { background: #e9f9ee; border-color: #bfe8cb; color: #147a3a; }

.ph-cm-title { font-size: 13px; font-weight: 700; color: var(--ph-ink); margin: 8px 0; }
.ph-cm-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 12px; }
.ph-cm {
    display: flex; gap: 8px; font-size: 13px;
}
.ph-cm .ph-cm-body { flex: 1; }
.ph-cm .ph-cm-author { font-weight: 700; color: var(--ph-ink); }
.ph-cm .ph-cm-text { color: var(--ph-ink); word-break: break-word; }
.ph-cm .ph-cm-tools { display: flex; gap: 8px; margin-top: 2px; }
.ph-cm .ph-cm-tools button { background: none; border: 0; color: var(--ph-muted); cursor: pointer; font-size: 11px; padding: 0; }
.ph-cm .ph-cm-tools button:hover { color: var(--ph-crimson); }
/* Block-account action: destructive and admin-only, so it reads as danger at rest
   rather than only on hover (the sibling .ph-danger rule is scoped to .ph-lb-actions). */
.ph-cm .ph-cm-tools .ph-danger { color: var(--ph-crimson); font-weight: 600; }
.ph-cm-empty { font-size: 12.5px; color: var(--ph-muted); }

.ph-cm-form { display: flex; gap: 8px; align-items: flex-end; }
.ph-cm-form textarea {
    flex: 1; resize: none; border: 1px solid var(--ph-line); border-radius: 10px;
    padding: 8px 10px; font-size: 13px; font-family: inherit; max-height: 90px;
}
.ph-cm-form textarea:focus { outline: none; border-color: var(--ph-crimson); }
.ph-cm-send {
    background: var(--ph-crimson); border: 0; color: #fff; cursor: pointer;
    border-radius: 10px; padding: 9px 14px; font-size: 13px; font-weight: 700;
}
.ph-cm-send:disabled { opacity: .5; cursor: not-allowed; }

/* Anonymous "join to comment / add photos" invite — replaces the comment box for logged-out viewers. */
.ph-cm-invite { padding: 14px; border-top: 1px solid var(--ph-line); text-align: center; }
.ph-cm-invite-t { font-size: 13.5px; font-weight: 700; color: var(--ph-ink); margin-bottom: 3px; }
.ph-cm-invite-b { font-size: 12.5px; color: var(--ph-muted); margin-bottom: 11px; line-height: 1.45; }
.ph-cm-invite-btns { display: flex; gap: 8px; justify-content: center; }
.ph-cm-invite-login, .ph-cm-invite-signup {
    flex: 1; max-width: 150px; text-align: center; text-decoration: none;
    font-size: 13px; font-weight: 700; padding: 9px 12px; border-radius: 10px;
}
.ph-cm-invite-login { background: var(--ph-crimson); color: #fff; }
.ph-cm-invite-login:hover { background: var(--ph-crimson-dark); color: #fff; }
.ph-cm-invite-signup { background: #f1f3f7; color: var(--ph-ink); border: 1px solid var(--ph-line); }
.ph-cm-invite-signup:hover { background: #e6e8ee; color: var(--ph-ink); }

/* caption field in upload */
.ph-cap-input {
    width: 100%; border: 1px solid var(--ph-line); border-radius: 8px;
    padding: 8px 10px; font-size: 12.5px; font-family: inherit; margin-top: 6px;
}
.ph-cap-input:focus { outline: none; border-color: var(--ph-crimson); }

/* ---- tag suggest list ---- */
.ph-tag-search {
    width: 100%; border: 1px solid var(--ph-line); border-radius: 10px;
    padding: 10px 12px; font-size: 14px; font-family: inherit; margin-bottom: 12px;
}
.ph-tag-search:focus { outline: none; border-color: var(--ph-crimson); }
.ph-tag-group-label { font-size: 11px; font-weight: 700; text-transform: uppercase; color: var(--ph-muted); margin: 12px 0 6px; letter-spacing: .04em; }
.ph-tag-item {
    display: flex; align-items: center; gap: 10px; width: 100%;
    background: none; border: 0; text-align: left; cursor: pointer;
    padding: 8px 6px; border-radius: 10px; font-size: 14px; color: var(--ph-ink);
}
.ph-tag-item:hover { background: #f7f8fb; }
.ph-tag-item img, .ph-tag-item .ph-tag-ph {
    width: 36px; height: 36px; border-radius: 50%; object-fit: cover;
    background: #e6e8ee; flex: 0 0 auto; display: flex; align-items: center; justify-content: center; color: var(--ph-muted);
}
/* suggest row: avatar + (name over team) */
.ph-tag-item-av { flex: 0 0 auto; display: flex; }
.ph-tag-item-meta { display: flex; flex-direction: column; min-width: 0; }
.ph-tag-item-name { font-size: 14px; color: var(--ph-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ph-tag-item-team { font-size: 12px; color: var(--ph-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ---- spatial tag layer + boxes over the lightbox image ---- */
.ph-lb-nav { z-index: 6; }
.ph-tag-layer {
    position: absolute; left: 0; top: 0; width: 0; height: 0;
    pointer-events: none; z-index: 4; visibility: hidden;
}
.ph-tag-box {
    position: absolute; box-sizing: border-box; pointer-events: auto;
    border: 2px solid transparent; border-radius: 4px;
    box-shadow: none;
    opacity: 0;                       /* hidden by default so the photo shows clean */
    transition: opacity .14s ease, box-shadow .12s ease, border-color .12s ease;
}
/* Reveal on demand: the whole layer is in "show all" mode (photo hover on desktop /
   the toggle on touch), OR this one box is active (its name hovered/tapped), OR the
   box itself is hovered. The pending placement box keeps its own always-on rule below. */
.ph-tag-layer.ph-show-tags .ph-tag-box,
.ph-tag-box.is-active,
.ph-tag-box:hover {
    opacity: 1;
    border-color: rgba(255, 255, 255, .9);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .35), inset 0 0 0 1px rgba(0, 0, 0, .15);
}
.ph-tag-box-link { cursor: pointer; }
.ph-tag-box.is-active, .ph-tag-box:hover {
    border-color: var(--ph-crimson);
    box-shadow: 0 0 0 2px var(--ph-crimson), 0 2px 10px rgba(0, 0, 0, .4);
}
.ph-tag-box-label {
    position: absolute; left: 50%; top: 100%; transform: translateX(-50%);
    margin-top: 5px; white-space: nowrap; max-width: 180px; overflow: hidden; text-overflow: ellipsis;
    background: rgba(20, 22, 28, .86); color: #fff; font-size: 11.5px; font-weight: 600;
    padding: 3px 8px; border-radius: 5px; opacity: 0; pointer-events: none; transition: opacity .12s ease;
}
.ph-tag-layer.ph-show-tags .ph-tag-box-label,
.ph-tag-box.is-active .ph-tag-box-label, .ph-tag-box:hover .ph-tag-box-label { opacity: 1; }

.ph-tag-pending {
    border-color: var(--ph-crimson); border-style: dashed;
    box-shadow: 0 0 0 2px rgba(215, 17, 73, .5), 0 2px 12px rgba(0, 0, 0, .4);
    cursor: move; touch-action: none;
    opacity: 1;                       /* a box being placed is always visible */
}

/* Touch-only "show tags" toggle pill, overlaid on the lightbox photo. Hidden on
   hover-capable pointers (desktop reveals boxes on photo hover instead) and only
   shown when the current photo actually has box tags (.ph-has-boxes set by JS). */
.ph-tags-toggle {
    position: absolute; left: 10px; bottom: 10px; z-index: 6;
    display: none; align-items: center; gap: 6px;
    background: rgba(20, 22, 28, .72); color: #fff; border: 0; cursor: pointer;
    padding: 7px 12px; border-radius: 999px; font-size: 12.5px; font-weight: 600; line-height: 1;
    -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
.ph-tags-toggle.is-on { background: var(--ph-crimson); }
.ph-tags-toggle .ph-tags-toggle-n:empty { display: none; }
@media (hover: none), (pointer: coarse) {
    .ph-lb-stage.ph-has-boxes .ph-tags-toggle { display: inline-flex; }
}
.ph-tag-resize {
    position: absolute; right: -7px; bottom: -7px; width: 16px; height: 16px;
    background: var(--ph-crimson); border: 2px solid #fff; border-radius: 50%;
    cursor: nwse-resize; touch-action: none;
}

/* inline search editor anchored to the pending box: input holds still, results OVERLAY below */
.ph-tag-editor { position: absolute; width: 260px; max-width: 80vw; pointer-events: auto; z-index: 7; }
.ph-tag-input {
    width: 100%; box-sizing: border-box; border: 1px solid var(--ph-line); border-radius: 10px;
    padding: 9px 12px; font-size: 14px; font-family: inherit; background: #fff;
    box-shadow: 0 6px 24px rgba(0, 0, 0, .28);
}
.ph-tag-input:focus { outline: none; border-color: var(--ph-crimson); }
.ph-tag-results-inline {
    position: absolute; left: 0; right: 0; top: 100%; margin-top: 6px;
    background: #fff; border-radius: 12px; box-shadow: 0 10px 30px rgba(0, 0, 0, .28);
    max-height: 260px; overflow-y: auto; padding: 6px;
}
.ph-tag-loading, .ph-tag-no-results, .ph-tag-error { font-size: 13px; color: var(--ph-muted); padding: 10px 8px; }
.ph-tag-error { color: var(--ph-crimson); }

/* ---- tag list in the side panel (visible to all viewers) ---- */
.ph-tag-list-wrap { margin-bottom: 14px; }
.ph-tag-list-head { font-size: 13px; font-weight: 700; color: var(--ph-ink); margin-bottom: 8px; }
.ph-tag-list { display: flex; flex-direction: column; gap: 2px; }
.ph-tag-row {
    display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ph-ink);
    padding: 5px 8px; border-radius: 8px; transition: background .12s ease;
}
.ph-tag-row > i { color: var(--ph-muted); font-size: 12px; width: 14px; text-align: center; flex: 0 0 auto; }
.ph-tag-row.is-active { background: rgba(215, 17, 73, .08); }
.ph-tag-name { color: var(--ph-ink); text-decoration: none; font-weight: 600; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
a.ph-tag-name:hover { color: var(--ph-crimson); text-decoration: underline; }
.ph-tag-row .ph-chip-rm { background: none; border: 0; color: var(--ph-muted); cursor: pointer; font-size: 14px; padding: 0 2px; flex: 0 0 auto; }
.ph-tag-row .ph-chip-rm:hover { color: var(--ph-crimson); }
.ph-tag-list-empty { font-size: 12.5px; color: var(--ph-muted); padding: 2px 0 6px; }
.ph-tag-hint { font-size: 11.5px; color: var(--ph-muted); margin-top: 8px; display: flex; align-items: center; gap: 6px; }

/* ---- lightbox side panel: make each SECTION + each COMMENT visually distinct ---- */
/* Host "what is this of" link (discovery feed) - a neutral chip at the top. */
.ph-lb-host {
    display: inline-flex; align-items: center; gap: 7px; margin-bottom: 12px;
    font-size: 14px; font-weight: 700; color: var(--ph-ink); text-decoration: none;
    background: #f1f3f7; padding: 7px 13px; border-radius: 999px;
}
.ph-lb-host:hover { background: #e6e8ee; text-decoration: none; color: var(--ph-ink); }
.ph-lb-host i { font-size: 13px; color: var(--ph-muted); }
/* Club crest(s) in the host pill: a match overlaps its two teams' logos. */
.ph-lb-host-logos { display: inline-flex; align-items: center; }
.ph-lb-host-logo {
    width: 20px; height: 20px; border-radius: 50%; object-fit: cover;
    background: #fff; border: 1px solid var(--ph-line);
}
.ph-lb-host-logo + .ph-lb-host-logo { margin-left: -6px; }
.ph-lb-host-name { min-width: 0; }
/* Divider line above each major panel section so they never blur together. */
.ph-tag-list-wrap, .ph-lb-actions { border-top: 1px solid var(--ph-line); padding-top: 13px; margin-top: 13px; }
.ph-cm-title { border-top: 1px solid var(--ph-line); padding-top: 13px; margin-top: 13px; }
/* Each comment is its own card (author in navy, text below) so they read distinctly. */
.ph-cm { background: #f7f8fb; border: 1px solid var(--ph-line); border-radius: 10px; padding: 9px 11px; }
.ph-cm .ph-cm-author { color: var(--ph-navy); font-weight: 700; }
.ph-cm .ph-cm-text { display: block; margin-top: 3px; }

/* ---- report reasons ---- */
.ph-reason { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
.ph-reason label {
    display: flex; align-items: center; gap: 10px; font-size: 14px; color: var(--ph-ink);
    padding: 10px 12px; border: 1px solid var(--ph-line); border-radius: 10px; cursor: pointer;
}
.ph-reason label:has(input:checked) { border-color: var(--ph-crimson); background: rgba(215, 17, 73, .04); }
.ph-reason input { accent-color: var(--ph-crimson); }
.ph-note-input {
    width: 100%; border: 1px solid var(--ph-line); border-radius: 10px;
    padding: 10px 12px; font-size: 13px; font-family: inherit; resize: vertical; min-height: 60px;
}
.ph-note-input:focus { outline: none; border-color: var(--ph-crimson); }

/* ---- tiny toast (standalone, works off member area) ---- */
.ph-toast {
    position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%) translateY(20px);
    background: var(--ph-ink); color: #fff; font-size: 13.5px; font-weight: 600;
    padding: 11px 20px; border-radius: 999px; z-index: 13000; max-width: 90vw; text-align: center;
    opacity: 0; visibility: hidden; transition: opacity .2s ease, transform .2s ease;
    box-shadow: 0 6px 20px rgba(0, 0, 0, .3);
}
.ph-toast.ph-show { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }
.ph-toast.ph-toast-error { background: var(--ph-crimson); }

/* ---- responsive: side panel becomes stacked on phones ---- */
@media (max-width: 640px) {
    .ph-lb-main { flex-direction: column; }
    .ph-lb-stage { min-height: 44vh; }
    .ph-lb-side { width: 100%; max-width: 100%; max-height: 46vh; border-top: 1px solid var(--ph-line); }
    .ph-grid { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }
    .ph-feed .ph-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
    /* On phones the side panel stacks BELOW the image, so the tag list already sits under
       the photo (Boss's "at the bottom" intent). Keep the inline editor within the frame. */
    .ph-tag-editor { width: 220px; }
    .ph-tag-results-inline { max-height: 200px; }
}

/* ---- admin management page tweaks (light on the admin white card) ---- */
.ph-manage-wrap { max-width: 900px; margin: 0 auto; }
.ph-manage-sub { color: var(--ph-muted); font-size: 13.5px; margin: 4px 0 16px; }
.ph-manage-empty {
    text-align: center; color: var(--ph-muted); padding: 30px 16px;
    border: 1px dashed var(--ph-line); border-radius: 12px;
}

/* ---- home "Foto Terbaru": exactly 4 BIG photos across on desktop (25% each) ----
   Placed last so it overrides the default auto-fill .ph-feed grid + its responsive rules.
   Collapses to 2 across on tablet/phone so the cards never get too small. */
/* Landing-page "Foto Terbaru": a justified-rows gallery (Flickr / Google-Photos style). The JS
   sizes each cell's width and the image height per row; CSS lays the rows out and strips the
   card chrome so the photos stand out. Handles mixed aspect ratios with no crop or misalignment. */
.ph-feed-justified .ph-grid { display: block; }
.ph-feed-justified .ph-jrow { display: flex; align-items: flex-start; margin-bottom: 12px; }
.ph-feed-justified .ph-jrow:last-child { margin-bottom: 0; }
.ph-feed-justified .ph-cell {
    flex: 0 0 auto; padding-top: 0; background: transparent;
    border: 0; border-radius: 0; overflow: visible; box-shadow: none;
}
.ph-feed-justified .ph-cell:hover { transform: none; }
.ph-feed-justified .ph-cell-img {
    padding-top: 0;               /* JS sets an explicit px height per row instead of a ratio */
    border-radius: 12px; box-shadow: var(--ph-shadow);
    transition: box-shadow .15s ease, transform .15s ease;
}
.ph-feed-justified .ph-cell:hover .ph-cell-img { box-shadow: var(--ph-shadow-hi); transform: translateY(-2px); }
.ph-feed-justified .ph-cap { background: transparent; padding: 8px 2px 2px; }

/* Loading skeleton (feed first-load placeholder). A soft block with a sweeping shimmer.
   Justified rows set width/height inline; grid cells use a 72% aspect box like real cells. */
.ph-skel {
    position: relative;
    border-radius: 12px;
    background: #e9ebf0;
    overflow: hidden;
}
.ph-skel::after {
    content: "";
    position: absolute; inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent 0, rgba(255, 255, 255, .65) 50%, transparent 100%);
    animation: ph-shimmer 1.25s ease-in-out infinite;
}
.ph-feed .ph-grid .ph-skel-cell { width: 100%; padding-top: 72%; }
/* Static first-paint skeleton (server-rendered inside .ph-grid). A responsive flex row of
   shimmer tiles that fills like the justified gallery, so the section holds its height before
   any JS runs. photo_social.js clears it once real photos land. */
.ph-skel-static { display: flex; flex-wrap: wrap; gap: 12px; }
.ph-skel-static .ph-skel { flex: 1 1 190px; height: 230px; }
@media (max-width: 640px) {
    .ph-skel-static { gap: 8px; }
    .ph-skel-static .ph-skel { flex: 1 1 140px; height: 200px; }
}
@keyframes ph-shimmer { 100% { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
    .ph-skel::after { animation: none; }
}
