:root{--gold:#ae9360;--gold-light:#ead7ab;--ink:#28251f;--muted:#736d62;--paper:#fff;--canvas:#f2f0eb;--line:#d9d1c2;--danger:#8f2f2f;--success:#2f6d45;--radius:18px}*{box-sizing:border-box}html{font-family:Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;color:var(--ink);background:var(--canvas)}body{margin:0}.skip-link{position:absolute;left:-9999px}.skip-link:focus{left:1rem;top:1rem;background:#fff;padding:.75rem;z-index:100}.screen-reader-text{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(1px,1px,1px,1px)}.portal-header{height:76px;background:#fff;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between;padding:0 clamp(20px,5vw,72px);position:sticky;top:0;z-index:20}.portal-brand{display:flex;align-items:center;gap:10px;color:inherit;text-decoration:none;font-weight:700}.portal-brand-mark{display:grid;place-items:center;background:var(--gold);color:#fff;width:34px;height:34px;border-radius:50%;font-family:Georgia,serif}.portal-header nav{display:flex;gap:20px}.portal-header nav a{color:inherit;text-decoration:none}.portal-main{width:min(1280px,calc(100% - 32px));min-height:calc(100vh - 150px);margin:0 auto;padding:clamp(40px,7vw,88px) 0}.portal-footer{text-align:center;color:var(--muted);padding:28px}.portal-auth-card{width:min(520px,100%);margin:5vh auto;background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:clamp(28px,6vw,56px);box-shadow:0 20px 60px rgba(52,45,31,.08)}.eyebrow{text-transform:uppercase;letter-spacing:.18em;color:var(--gold);font-size:.78rem;font-weight:700}.portal-auth-card h1,.portal-heading h1{font-family:Georgia,"Times New Roman",serif;font-size:clamp(2rem,5vw,4rem);line-height:1;margin:.2em 0}.portal-form{display:grid;gap:18px;margin-top:28px}.portal-form label{font-weight:650;display:grid;gap:7px}.portal-form input,.gallery-search input{min-height:46px;border:1px solid var(--line);border-radius:10px;padding:10px 13px;font:inherit}.portal-button{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:10px 18px;border:1px solid var(--gold);border-radius:999px;background:#fff;color:var(--ink);text-decoration:none;font:inherit;font-weight:700;cursor:pointer}.portal-button-primary{background:var(--gold);color:#fff}.portal-button:focus-visible,input:focus-visible{outline:3px solid var(--gold-light);outline-offset:2px}.portal-help{font-size:.9rem;color:var(--muted);margin-top:24px}.hp-field{position:absolute;left:-9999px}.portal-alert{padding:14px 18px;border:1px solid var(--gold);background:#fff8e8;border-radius:10px;margin:18px 0}.portal-alert-error{border-color:#d5a4a4;background:#fff1f1;color:var(--danger)}.portal-alert-success{border-color:#a8cbb5;background:#f0fff4;color:var(--success)}.portal-heading{margin-bottom:34px}.portal-heading-with-actions{display:flex;align-items:end;justify-content:space-between;gap:24px}.selection-counter{background:#fff;border:1px solid var(--line);border-radius:999px;padding:12px 20px;white-space:nowrap}.selection-counter strong{font-size:1.5rem;color:var(--gold)}.project-list{display:grid;gap:18px}.project-card{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:28px;display:flex;align-items:center;justify-content:space-between;gap:24px}.project-card h2{font-family:Georgia,serif;font-size:1.8rem;margin:.5em 0}.project-card dl{display:flex;flex-wrap:wrap;gap:22px;margin:0}.project-card dl div{display:grid}.project-card dt{font-size:.75rem;color:var(--muted);text-transform:uppercase;letter-spacing:.08em}.project-card dd{margin:4px 0}.status-badge{font-size:.72rem;text-transform:uppercase;letter-spacing:.08em;background:var(--gold-light);padding:6px 10px;border-radius:99px}.gallery-toolbar{display:flex;justify-content:space-between;gap:16px;align-items:center;margin-bottom:22px}.gallery-search{display:flex;flex-wrap:wrap;gap:10px;align-items:center}.checkbox-inline{display:flex;gap:7px;align-items:center}.drive-fallback{color:var(--ink)}.client-gallery{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:12px;align-items:start}.gallery-item{min-width:0;background:#fff;border:2px solid transparent;border-radius:12px;padding:6px;transition:border .15s,transform .15s}.gallery-item.is-selected{border-color:var(--gold);transform:translateY(-2px)}.gallery-item label{cursor:pointer}.gallery-image-wrap{display:block;position:relative;aspect-ratio:var(--item-ratio,4/5);background:#ddd1ba;border-radius:8px;overflow:hidden}.gallery-image-wrap img{width:100%;height:100%;object-fit:cover;display:block}.gallery-placeholder{display:grid;place-items:center;width:100%;height:100%;font-size:.78rem;color:#605644}.selection-check{position:absolute;left:8px;bottom:8px;background:rgba(255,255,255,.92);padding:7px 9px;border-radius:999px;display:flex;gap:5px;align-items:center;font-size:.76rem}.filename{display:block;font-size:.75rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:8px 2px 2px}.sticky-actions{position:sticky;bottom:14px;display:flex;justify-content:center;gap:10px;background:rgba(255,255,255,.95);border:1px solid var(--line);border-radius:999px;padding:10px;margin:28px auto;width:max-content;max-width:100%;z-index:10}.pagination{display:flex;justify-content:center;gap:8px;margin:30px}.pagination a{display:grid;place-items:center;width:42px;height:42px;border:1px solid var(--line);background:#fff;border-radius:50%;text-decoration:none;color:inherit}.pagination a.current{background:var(--gold);color:#fff}.portal-empty{background:#fff;border:1px dashed var(--line);border-radius:var(--radius);padding:50px;text-align:center}.review-summary{background:#fff;border:1px solid var(--line);padding:18px;border-radius:12px;margin-bottom:20px}.review-summary strong{font-size:1.6rem;color:var(--gold)}.review-grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:12px}.review-grid article{background:#fff;padding:7px;border-radius:10px}.review-grid img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:7px}.review-grid .gallery-placeholder{aspect-ratio:1;border-radius:7px;background:#ddd1ba}.review-remove-form .portal-button{width:100%;min-height:36px;padding:7px 12px}.review-grid p{font-size:.72rem;overflow-wrap:anywhere}.review-actions{display:flex;justify-content:space-between;gap:12px;margin-top:30px}.submission-code{display:grid;background:var(--canvas);padding:16px;border-radius:10px;margin:24px 0}.submission-code span{font-size:.75rem;color:var(--muted);text-transform:uppercase}.submission-code strong{font-size:1.3rem}.portal-success .portal-button{width:100%;margin-top:10px}@media(max-width:1050px){.client-gallery{grid-template-columns:repeat(4,minmax(0,1fr))}.review-grid{grid-template-columns:repeat(4,minmax(0,1fr))}}@media(max-width:700px){.portal-header{height:66px;padding:0 16px}.portal-brand span:last-child{display:none}.portal-main{width:min(100% - 20px,1280px);padding:34px 0}.portal-heading-with-actions,.project-card,.gallery-toolbar,.review-actions{align-items:stretch;flex-direction:column}.project-card dl{display:grid;grid-template-columns:1fr 1fr}.client-gallery{grid-template-columns:repeat(2,minmax(0,1fr));gap:7px}.review-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:7px}.sticky-actions{width:calc(100% - 8px);border-radius:16px;flex-direction:column}.gallery-search{display:grid;grid-template-columns:1fr}.gallery-search input[type=search]{width:100%}.portal-auth-card{padding:28px 22px}.portal-heading h1{font-size:2.5rem}}@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important;transition:none!important}}

.portal-download-actions{display:flex;flex-wrap:wrap;gap:.75rem;margin:1rem 0 .45rem}.portal-download-note{font-size:.88rem;opacity:.75;margin:.25rem 0 1.2rem}
@media(max-width:600px){.portal-download-actions .portal-button{width:100%;text-align:center}}

.portal-download-actions{display:flex;flex-wrap:wrap;gap:.75rem;margin:1rem 0 .45rem}.portal-download-note{font-size:.88rem;opacity:.75;margin:.25rem 0 1.2rem}
@media(max-width:600px){.portal-download-actions .portal-button{width:100%;text-align:center}}

/* 1.6.0 fast preview + lightbox */
.gallery-image-wrap{isolation:isolate}
.gallery-image-wrap img{background:#ddd1ba}
.gallery-load-error{position:absolute;inset:0;background:#ddd1ba;z-index:1}
.gallery-view-button{position:absolute;top:8px;right:8px;z-index:4;width:38px;height:38px;border:1px solid rgba(255,255,255,.75);border-radius:999px;background:rgba(24,22,18,.78);color:#fff;display:grid;place-items:center;font:700 20px/1 system-ui;cursor:pointer;box-shadow:0 4px 18px rgba(0,0,0,.22);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
.gallery-view-button:hover{background:rgba(24,22,18,.95);transform:translateY(-1px)}
.gallery-view-button:focus-visible{outline:3px solid var(--gold-light);outline-offset:2px}
.review-image-wrap{position:relative;aspect-ratio:1;overflow:hidden;border-radius:7px;background:#ddd1ba}
.review-image-wrap img{width:100%;height:100%;object-fit:cover}
.portal-lightbox[hidden]{display:none!important}
.portal-lightbox{position:fixed;inset:0;z-index:100000;background:rgba(10,10,10,.94);display:grid;grid-template-rows:1fr auto;place-items:center;padding:clamp(14px,3vw,32px)}
.portal-lightbox-stage{position:relative;width:100%;height:100%;display:grid;place-items:center;overflow:auto;overscroll-behavior:contain}
.portal-lightbox-stage img{display:block;max-width:min(96vw,1800px);max-height:86vh;width:auto;height:auto;object-fit:contain;border-radius:10px;box-shadow:0 20px 70px rgba(0,0,0,.45)}
.portal-lightbox-loading{position:absolute;color:#fff;background:rgba(0,0,0,.55);padding:10px 16px;border-radius:999px}
.portal-lightbox-close{position:fixed;top:max(14px,env(safe-area-inset-top));right:max(14px,env(safe-area-inset-right));z-index:2;width:48px;height:48px;border:1px solid rgba(255,255,255,.4);border-radius:50%;background:rgba(0,0,0,.6);color:#fff;font:300 34px/1 system-ui;cursor:pointer}
.portal-lightbox-filename{margin:12px 0 0;color:#fff;text-align:center;overflow-wrap:anywhere}
body.portal-lightbox-open{overflow:hidden}
@media(max-width:700px){.gallery-view-button{width:36px;height:36px;top:6px;right:6px}}

/* ===== Lightbox responsif: foto selalu center, nav di kiri/kanan ===== */
.portal-lightbox{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:0}
.portal-lightbox-stage{flex:1 1 auto;display:flex;align-items:center;justify-content:center;width:100%;min-height:0;padding:clamp(52px,9vh,88px) clamp(58px,14vw,110px) 8px;box-sizing:border-box;overflow:hidden}
.portal-lightbox-stage img{display:block;max-width:100%;max-height:100%;width:auto;height:auto;margin:auto;object-fit:contain;border-radius:8px;box-shadow:0 20px 70px rgba(0,0,0,.45);touch-action:pan-y}
.portal-lightbox-bar{flex:0 0 auto;width:100%;padding:10px clamp(12px,4vw,24px) max(14px,env(safe-area-inset-bottom));box-sizing:border-box}
.portal-lightbox-filename{color:#fff;font-size:14px}
.portal-lightbox-check{color:#fff;background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.35)}
.portal-lightbox-check input{accent-color:#c9a24a}
@media(max-width:820px){
  .portal-lightbox-stage{padding:clamp(46px,8vh,66px) 8px 6px}
  .portal-lightbox-nav{width:44px;height:44px;font-size:26px;background:rgba(0,0,0,.55);border:1px solid rgba(255,255,255,.28)}
  .portal-lightbox-prev{left:8px}
  .portal-lightbox-next{right:8px}
  .portal-lightbox-close{width:42px;height:42px;font-size:28px}
  .portal-lightbox-bar{flex-direction:column;gap:10px}
  .portal-lightbox-filename{font-size:13px}
}

/* 1.7.2: selection remains usable when preview loading fails */
.gallery-load-error{pointer-events:none}
.selection-check{z-index:5;pointer-events:auto;box-shadow:0 3px 12px rgba(0,0,0,.16)}
.selection-check input{position:relative;z-index:1}

/* 1.7.3 resilient gallery loading and clearer controls */
.gallery-image-wrap{min-height:0;background:#ddd1ba}
.gallery-image-wrap.is-loading::before{content:"";position:absolute;inset:0;background:linear-gradient(110deg,#ddd1ba 8%,#eee7d8 18%,#ddd1ba 33%);background-size:200% 100%;animation:lily-gallery-shimmer 1.25s linear infinite;z-index:0}
.gallery-loading{position:absolute;left:50%;top:50%;z-index:2;transform:translate(-50%,-50%);padding:.45rem .7rem;border-radius:999px;background:rgba(255,255,255,.84);color:#5d513e;font-size:.72rem;white-space:nowrap;pointer-events:none}
.gallery-image-wrap:not(.is-loading) .gallery-loading{display:none}
.gallery-load-error{z-index:2;display:flex!important;flex-direction:column;gap:.55rem;align-items:center;justify-content:center;padding:1rem;text-align:center}
.gallery-load-error[hidden]{display:none!important}
.gallery-retry-button{appearance:none;border:1px solid rgba(45,38,27,.35);border-radius:999px;background:#fff;color:var(--ink);font:700 .72rem/1 system-ui;padding:.55rem .8rem;cursor:pointer;pointer-events:auto}
.gallery-retry-button:hover{background:#f8f3e8}
.selection-check{left:8px!important;bottom:8px!important;z-index:8!important;min-height:36px;padding:8px 11px!important;background:#fff!important;color:#201d18!important;border:1px solid rgba(52,45,31,.18);font-weight:750;opacity:1!important;visibility:visible!important}
.selection-check input{width:18px;height:18px;margin:0}
.gallery-view-button{z-index:8}
.portal-lightbox-stage img{image-rendering:auto}
@keyframes lily-gallery-shimmer{to{background-position-x:-200%}}
@media(max-width:700px){.selection-check{min-height:34px;padding:7px 9px!important;font-size:.72rem}.gallery-loading{font-size:.68rem}.gallery-load-error{font-size:.72rem}}
@media(prefers-reduced-motion:reduce){.gallery-image-wrap.is-loading::before{animation:none}}


/* 1.7.3 resilient gallery controls */
.gallery-image-wrap{isolation:isolate}
.gallery-image-wrap .selection-check{position:absolute!important;left:.6rem!important;bottom:.6rem!important;z-index:30!important;display:flex!important;visibility:visible!important;opacity:1!important;pointer-events:auto!important;background:rgba(255,255,255,.96)!important;color:#171512!important;border:1px solid rgba(23,21,18,.18)!important;box-shadow:0 5px 18px rgba(0,0,0,.14)!important}
.gallery-image-wrap .gallery-view-button{z-index:31!important}
.gallery-image-wrap .gallery-load-error,.gallery-image-wrap .gallery-loading{z-index:10!important;pointer-events:none!important}
.gallery-image-wrap .gallery-load-error .gallery-retry-button{pointer-events:auto!important}
.gallery-image-wrap.has-error{background:linear-gradient(135deg,#eee6d6,#d8c59a)}
@media(max-width:760px){.gallery-image-wrap .selection-check{min-height:40px;padding:.45rem .65rem!important;font-size:.88rem}}


/* 1.0.6 — portal logo, square checkbox, password visibility, and iOS zoom prevention. */
.portal-brand{min-width:0}
.portal-brand-logo{display:block;width:clamp(150px,18vw,205px);height:auto;max-height:58px;object-fit:contain;object-position:left center}
.portal-form input:not([type="checkbox"]),.gallery-search input:not([type="checkbox"]),.portal-form select,.portal-form textarea{
  min-width:0;min-height:46px;font-size:16px;touch-action:manipulation;
}
.portal-checkbox-row,.checkbox-inline{display:flex!important;align-items:center;gap:9px;font-weight:650;cursor:pointer}
.portal-checkbox-row input[type="checkbox"],.checkbox-inline input[type="checkbox"],.selection-check input[type="checkbox"]{
  appearance:auto!important;-webkit-appearance:checkbox!important;flex:0 0 20px!important;width:20px!important;height:20px!important;
  min-width:20px!important;min-height:20px!important;margin:0!important;padding:0!important;border-radius:3px!important;accent-color:var(--gold);
}
@media(max-width:700px){
  .portal-brand-logo{width:170px;max-height:50px}
  .portal-form input:not([type="checkbox"]),.gallery-search input:not([type="checkbox"]),.portal-form select,.portal-form textarea{font-size:16px!important}
}

/* Lily Client Portal 1.0.9 account panel */
.portal-account-card{display:grid;grid-template-columns:minmax(0,1fr) minmax(260px,420px);gap:18px;align-items:start;margin:24px 0;padding:clamp(18px,3vw,28px);border:1px solid rgba(177,154,107,.28);border-radius:24px;background:#fff;box-shadow:0 18px 42px rgba(0,0,0,.06)}.portal-account-form{display:grid;gap:12px}.portal-account-form label{display:grid;gap:6px;font-weight:700}.portal-account-form input{width:100%;box-sizing:border-box;border:1px solid rgba(0,0,0,.14);border-radius:12px;padding:12px}.portal-notice{margin:16px 0;padding:12px 14px;border-radius:12px}.portal-notice-success{background:#effbea;border:1px solid #b9e6a7}.portal-notice-error{background:#fff0f0;border:1px solid #e8b2b2}.portal-empty-inline{padding:12px;border-radius:12px;background:#f7f2e6}@media(max-width:760px){.portal-account-card{grid-template-columns:1fr}}

/* 1.0.12 — accessible credential change on login and shared account form. */
.portal-alert-success{background:#effbea;border:1px solid #b9e6a7;color:#245f2b}
.portal-text-button{appearance:none;border:0;background:transparent;color:var(--gold);padding:10px 0;font:700 1rem/1.4 inherit;text-decoration:underline;text-underline-offset:3px;cursor:pointer}.portal-text-button:hover{color:var(--ink)}.portal-text-button:focus-visible{outline:3px solid rgba(177,148,84,.35);outline-offset:4px;border-radius:4px}
.portal-credential-panel[hidden]{display:none!important}.portal-credential-panel{margin-top:16px;padding-top:20px;border-top:1px solid var(--line)}.portal-credential-panel h2{margin-top:0}.portal-credential-panel .portal-form{margin-top:16px}
/* J6: kolom readonly berisi NILAI NYATA (username aktif). Sebelumnya diberi warna var(--muted) sehingga terlihat seperti placeholder kosong. Warna teks dikembalikan ke warna utama; latar abu-abu sudah cukup menandakan kolom terkunci. */
.portal-account-form input[readonly]{background:#f3efe6;color:var(--ink);font-weight:650;cursor:not-allowed}
/* J6: teks anjuran panjang password. */
.portal-hint{font-size:.86rem;color:var(--muted);line-height:1.5;margin:2px 0 0}
@media(max-width:700px){.portal-text-button{min-height:44px;text-align:left}.portal-credential-panel{scroll-margin-top:80px}.portal-auth-card input:not([type="checkbox"]),.portal-account-form input:not([type="checkbox"]){font-size:16px!important}}

/* v1.0.12 account control */
.portal-account-change-panel[hidden]{display:none}.portal-account-change-panel{width:100%;margin-top:16px}.portal-inline-actions{display:flex;gap:10px;flex-wrap:wrap}.portal-account-form input:focus-visible,.portal-button:focus-visible{outline:3px solid rgba(169,144,95,.45);outline-offset:2px}

/* v1.0.12 selection review and accessible replacement dialog. */
.review-item-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.review-item-actions form{margin:0}.portal-button-quiet{background:transparent;border-color:rgba(35,35,35,.2)}
.portal-replace-modal[hidden]{display:none!important}.portal-replace-modal{position:fixed;inset:0;z-index:100000;display:grid;place-items:center;padding:20px;background:rgba(18,16,12,.68);overflow:auto}.portal-replace-dialog{position:relative;width:min(980px,100%);max-height:min(88vh,900px);overflow:auto;background:#fff;border-radius:18px;padding:24px;box-shadow:0 30px 80px rgba(0,0,0,.3)}.portal-replace-close{position:absolute;top:12px;right:14px;width:42px;height:42px;border:0;border-radius:50%;background:#f1ede5;font-size:28px;line-height:1;cursor:pointer}.portal-replace-search{display:grid;gap:7px;margin:18px 0}.portal-replace-search>div{display:flex;gap:8px}.portal-replace-search input{min-width:0;flex:1}.portal-replace-status{min-height:24px;margin:8px 0}.portal-replace-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px}.portal-replace-item{min-width:0;display:grid;gap:8px;align-content:start}.portal-replace-item img{display:block;width:100%;aspect-ratio:1/1;object-fit:cover;border-radius:10px;background:#eee9df}.portal-replace-item span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}.portal-replace-item .portal-button{width:100%;padding-inline:8px}.portal-replace-more{display:block;margin:20px auto 0}.portal-modal-open{overflow:hidden}
@media(max-width:760px){.portal-replace-modal{padding:8px;place-items:end center}.portal-replace-dialog{max-height:92vh;border-radius:18px 18px 0 0;padding:20px 16px}.portal-replace-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.portal-replace-search>div{align-items:stretch}.portal-replace-search .portal-button{padding-inline:14px}}

/* 1.0.12 — stable selection state, modal viewport, and touch controls. */
.portal-shell,.portal-shell *{box-sizing:border-box}
.portal-shell :is(button,a,input,select,textarea):focus-visible{outline:3px solid currentColor;outline-offset:3px}
.portal-shell button[aria-busy=true]{cursor:wait;opacity:.7}
.portal-replace-modal{padding:clamp(10px,3vw,28px)}
.portal-replace-dialog{width:min(1040px,100%);max-height:calc(100dvh - 20px);overflow:auto;overscroll-behavior:contain}
.portal-replace-item{min-width:0}.portal-replace-item span{overflow-wrap:anywhere}
@media(max-width:700px){
 .portal-actions,.portal-review-actions{display:grid;grid-template-columns:1fr;gap:10px}
 .portal-actions .portal-button,.portal-review-actions .portal-button,.portal-actions form,.portal-review-actions form{width:100%}
 .portal-button{min-height:46px;display:inline-flex;align-items:center;justify-content:center;text-align:center}
 .portal-replace-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media(max-width:420px){.portal-replace-grid{grid-template-columns:1fr}}

/* ===== Folder browser (deteksi otomatis isi Drive) ===== */
.portal-folder-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:14px;margin:18px 0}
.portal-folder-card{display:flex;flex-direction:column;gap:4px;padding:16px;border:1px solid #e2dccd;border-radius:14px;background:#fff;text-decoration:none;color:#2c2a26;transition:box-shadow .15s ease,transform .15s ease}
.portal-folder-card:hover{box-shadow:0 6px 18px rgba(60,50,30,.12);transform:translateY(-2px)}
.portal-folder-card.is-current{border-color:#b9a26b;background:#faf7f0}
.portal-folder-icon{font-size:26px;line-height:1}
.portal-folder-card small{color:#7a7264}
.portal-section-title{margin:26px 0 10px;font-size:20px}
.portal-video-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:18px}
.portal-video-card{background:#fff;border:1px solid #e2dccd;border-radius:14px;padding:12px}
.portal-video-frame{position:relative;width:100%;aspect-ratio:16/9;border-radius:10px;overflow:hidden;background:#000}
.portal-video-frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
/* Q3a: kartu video mengalami pemutusan yang sama pada nama berkas. */
.portal-video-card p{margin:10px 0 8px;font-size:14px;overflow-wrap:anywhere;word-break:normal}
.gallery-item-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:8px 10px}
.gallery-filename{font-size:12.5px;color:#5c5648}
/* Q3a: `word-break:break-word` memutus di posisi mana pun, sehingga
   "WLY09030.JPG" tampil sebagai "WLY09030.jp" + "g" di baris berikutnya.
   Nama kini satu baris; bila terlalu panjang dipotong dengan elipsis —
   penanda yang jelas bahwa nama dipendekkan, bukan kata yang rusak.
   Nama utuh tetap dapat dibaca lewat atribut title dan pembaca layar.
   `min-width:0` wajib karena elemen ini anak flex; tanpa itu elipsis
   tidak pernah aktif. */
.gallery-filename{min-width:0;flex:1 1 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

.portal-button-small{padding:6px 12px;font-size:12.5px}
.portal-button-primary{background:#8a744a;color:#fff;border-color:#8a744a}
.portal-button-primary:hover{background:#75613c}

/* ===== Video: thumbnail + lightbox player ===== */
.portal-video-thumb{position:relative;display:block;width:100%;aspect-ratio:var(--item-ratio,16/9);border:0;padding:0;border-radius:10px;overflow:hidden;background:#111;cursor:pointer}
.portal-video-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.portal-video-play{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;transition:transform .15s ease}
.portal-video-thumb:hover .portal-video-play{transform:scale(1.08)}
/* WAJIB: display:flex menimpa [hidden] bawaan browser. Tanpa baris ini
   pemutar video akan selalu tampil sebagai layar hitam. */
.portal-video-lightbox[hidden]{display:none!important}
.portal-video-lightbox{position:fixed;inset:0;z-index:99999;background:rgba(15,12,8,.94);display:flex;align-items:center;justify-content:center;padding:24px}
.portal-video-lightbox-stage{width:min(960px,94vw)}
.portal-video-lightbox-frame{position:relative;width:100%;aspect-ratio:16/9;background:#000;border-radius:12px;overflow:hidden}
.portal-video-lightbox-frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.portal-video-lightbox .portal-lightbox-filename{color:#f4efe6;text-align:center;margin-top:12px}
.portal-video-lightbox .portal-lightbox-close{position:absolute;top:18px;right:24px;font-size:32px;line-height:1;color:#fff;background:none;border:0;cursor:pointer}

/* ===== Lightbox: navigasi next/prev + checkbox pilih ===== */
.portal-lightbox-nav{position:absolute;top:50%;transform:translateY(-50%);width:52px;height:52px;border-radius:50%;border:0;background:rgba(0,0,0,.45);color:#fff;font-size:34px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:2;transition:background .15s ease}
.portal-lightbox-nav:hover{background:rgba(0,0,0,.7)}
.portal-lightbox-nav:disabled{opacity:.25;cursor:default}
.portal-lightbox-prev{left:18px}
.portal-lightbox-next{right:18px}
.portal-lightbox-bar{display:flex;align-items:center;justify-content:center;gap:20px;flex-wrap:wrap;margin-top:12px}
.portal-lightbox-check{display:inline-flex;align-items:center;gap:8px;color:#f4efe6;background:rgba(0,0,0,.4);padding:8px 16px;border-radius:24px;cursor:pointer;font-size:15px}
.portal-lightbox-check input{width:18px;height:18px;cursor:pointer}
@media (max-width:600px){.portal-lightbox-nav{width:42px;height:42px;font-size:26px}.portal-lightbox-prev{left:8px}.portal-lightbox-next{right:8px}}

/* ===== Kompatibilitas lintas-perangkat & browser (1.0.24) =====
   aspect-ratio baru didukung Safari 15+/Chrome 88+. Pada browser lama tanpa
   dukungan, tinggi elemen bisa menjadi 0 sehingga galeri tampak kosong.
   Blok berikut memberi tinggi cadangan agar tampilan tetap benar. */
@supports not (aspect-ratio: 1 / 1) {
  .gallery-image-wrap{height:0;padding-bottom:125%;position:relative}
  .gallery-image-wrap img,
  .gallery-image-wrap .gallery-placeholder,
  .gallery-image-wrap .gallery-loading{position:absolute;top:0;left:0;width:100%;height:100%}
  .review-grid img{height:180px;object-fit:cover}
  .portal-video-thumb{height:0;padding-bottom:56.25%;position:relative}
  .portal-video-lightbox-frame{height:0;padding-bottom:56.25%;position:relative}
}
/* Posisi penuh layar ditulis eksplisit (inset shorthand baru didukung
   Safari 14.1+), agar lightbox tetap benar di iOS/macOS versi lama. */
.portal-lightbox,.portal-video-lightbox{top:0;right:0;bottom:0;left:0}
/* Sasaran sentuh minimal 44px sesuai pedoman iOS & Android. */
.portal-lightbox-nav,.portal-lightbox-close,.gallery-view-button{min-width:44px;min-height:44px}
/* Cegah zoom otomatis iOS saat fokus ke input (font < 16px). */
@media (max-width:820px){
  .portal-form input,.gallery-search input,input[type=search],input[type=text],input[type=password]{font-size:16px}
}

/* ===== Popup progres pembuatan ZIP (kanan bawah, semua perangkat) ===== */
.lily-zip-toast{position:fixed;right:16px;bottom:16px;z-index:100001;display:none;align-items:center;gap:12px;max-width:min(360px,calc(100vw - 32px));padding:14px 16px;border-radius:14px;background:#241f17;color:#fdfbf6;box-shadow:0 18px 44px rgba(0,0,0,.32);font-size:14px}
.lily-zip-toast.is-visible{display:flex}
.lily-zip-text{display:flex;flex-direction:column;gap:3px;min-width:0}
.lily-zip-text strong{font-size:14px;font-weight:700}
.lily-zip-text small{font-size:12px;color:#d8cdb8;line-height:1.35}
.lily-zip-spinner{flex:0 0 22px;width:22px;height:22px;border-radius:50%;border:3px solid rgba(255,255,255,.25);border-top-color:#e2c68a;animation:lily-zip-spin .9s linear infinite}
.lily-zip-toast.is-done .lily-zip-spinner{border-top-color:#7fce9a;animation:none;position:relative}
.lily-zip-toast.is-done .lily-zip-spinner::after{content:"";position:absolute;left:6px;top:2px;width:6px;height:11px;border:solid #7fce9a;border-width:0 3px 3px 0;transform:rotate(45deg)}
@keyframes lily-zip-spin{to{transform:rotate(360deg)}}
@media(max-width:600px){.lily-zip-toast{right:10px;left:10px;bottom:10px;max-width:none}}
@media(prefers-reduced-motion:reduce){.lily-zip-spinner{animation:none}}

/* P2: keterangan halaman + tombol langkah. `.pagination a` dipatok 42px bulat, jadi tombol berteks perlu lebar otomatis agar tidak terpotong. */
.pagination-status{text-align:center;color:var(--muted);margin:26px 0 -14px;font-size:.92rem}
.pagination-status strong{color:var(--ink)}
.pagination{flex-wrap:wrap}
.pagination a.pagination-step{width:auto;min-width:44px;padding:0 16px;border-radius:999px;font-weight:650;white-space:nowrap}

/* P3: tombol unduh per foto di galeri utama.
   Sudut kanan atas = tombol preview besar, kiri bawah = checkbox pilihan,
   sehingga tombol ini ditaruh di kanan bawah agar tidak ada yang tertutup. */
.gallery-download-button{position:absolute;right:8px;bottom:8px;z-index:4;width:38px;height:38px;border:1px solid rgba(255,255,255,.75);border-radius:999px;background:rgba(24,22,18,.78);color:#fff;display:grid;place-items:center;text-decoration:none;cursor:pointer;box-shadow:0 4px 18px rgba(0,0,0,.22);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
.gallery-download-button:hover,.gallery-download-button:focus-visible{background:var(--gold)}
/* Di layar sempit kartu mengecil; checkbox dan tombol unduh diberi jarak   agar tetap tidak bersinggungan. */
@media(max-width:700px){.gallery-download-button{width:34px;height:34px;right:6px;bottom:6px}.selection-check{left:6px;bottom:6px;padding:6px 8px;font-size:.72rem}}

/* P3: tombol melayang "Simpan Pilihan & Preview" bersifat sticky sehingga
   mengambang di atas grid saat menggulir dan sempat menutupi checkbox
   thumbnail di bawahnya.
   Perbaikan sengaja TIDAK mengubah posisi tombol simpan (fungsi utama
   harus tetap mudah dijangkau), melainkan memberi ruang bebas di bawah
   grid agar baris terakhir tidak pernah terperangkap di bawah tombol.
   Kartu yang tertutup di tengah gulungan selalu bisa dibuka dengan
   menggulir sedikit, karena tombolnya sticky — bukan fixed. */
.client-gallery{padding-bottom:92px}
@media(max-width:700px){.client-gallery{padding-bottom:132px}}
/* Beri sedikit transparansi saat tidak disentuh agar thumbnail di baliknya
   tetap terlihat, lalu pekat kembali ketika diarahkan/difokus. */
.sticky-actions{opacity:.94;transition:opacity .15s}
.sticky-actions:hover,.sticky-actions:focus-within{opacity:1}

/* P5: penukar bahasa di header portal. */
.portal-lang-toggle{display:inline-flex;align-items:center;min-height:36px;padding:6px 14px;margin-left:14px;border:1px solid var(--line);border-radius:999px;color:var(--ink);text-decoration:none;font-size:.85rem;font-weight:650;white-space:nowrap}
.portal-lang-toggle:hover,.portal-lang-toggle:focus-visible{border-color:var(--gold);color:var(--gold)}
@media(max-width:700px){.portal-lang-toggle{margin-left:8px;padding:5px 10px;font-size:.78rem}}

/* ============================================================
   GALERI MASONRY + PENYEGARAN VISUAL
   Hanya tampilan. Struktur form, nama field, dan checkbox tidak
   disentuh sama sekali agar alur pilih foto tetap utuh.
   ============================================================ */

/* Satuan baris halus dipakai JS untuk menghitung rentang tiap item.
   Tanpa JS kelas .is-masonry tidak pernah dipasang dan grid lama tetap jalan. */
.client-gallery{--masonry-unit:4px;--masonry-gap:14px}
.client-gallery.is-masonry{
  grid-auto-rows:var(--masonry-unit);
  row-gap:0;
  column-gap:var(--masonry-gap);
  align-items:stretch
}
.client-gallery.is-masonry > .gallery-item{align-self:start}

/* --- Kartu foto --- */
.gallery-item{
  border-width:2px;border-radius:14px;padding:5px;
  background:#fff;box-shadow:0 1px 2px rgba(31,24,12,.05);
  transition:box-shadow .18s ease,border-color .18s ease,transform .18s ease
}
.gallery-item:hover{box-shadow:0 6px 18px rgba(31,24,12,.10)}
.gallery-item.is-selected{
  border-color:var(--gold);
  box-shadow:0 6px 20px rgba(169,144,95,.28);
  transform:none
}
/* Penanda terpilih yang terbaca sekilas, tidak hanya lewat warna tepi. */
.gallery-item.is-selected .gallery-image-wrap::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  border-radius:inherit;box-shadow:inset 0 0 0 3px var(--gold)
}
.gallery-image-wrap{border-radius:10px}

/* --- Kontrol di atas foto ---
   Foto terang membuat ikon putih hilang. Lapisan gelap tipis di sudut
   menjaga kontras tanpa menutupi wajah di tengah bingkai. */
.gallery-image-wrap::before{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:1;
  background:
    linear-gradient(to bottom, rgba(0,0,0,.28), rgba(0,0,0,0) 34%),
    linear-gradient(to top, rgba(0,0,0,.30), rgba(0,0,0,0) 34%);
  opacity:0;transition:opacity .18s ease
}
.gallery-item:hover .gallery-image-wrap::before,
.gallery-item:focus-within .gallery-image-wrap::before,
.gallery-item.is-selected .gallery-image-wrap::before{opacity:1}

.gallery-view-button,.gallery-download-button,.selection-check{z-index:2}

/* --- Nama berkas --- */
.gallery-item .filename,.gallery-item .gallery-filename{
  display:block;margin-top:6px;padding:0 3px;
  font-size:12px;line-height:1.35;color:#6f6552;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap
}

/* --- Sentuhan di layar kecil ---
   Panduan UX: jarak antar target sentuh minimal 8px (sebelumnya 7px). */
@media(max-width:640px){
  .client-gallery{--masonry-gap:10px;gap:10px}
  .gallery-item{padding:4px;border-radius:12px}
  .gallery-view-button,.gallery-download-button{min-width:44px;min-height:44px}
  .selection-check{min-height:44px}
  /* Kontrol selalu terlihat di sentuh — tidak ada keadaan hover di ponsel. */
  .gallery-image-wrap::before{opacity:1}
}

/* --- Kartu folder: sedikit lebih hidup --- */
.portal-folder-card{transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease}
.portal-folder-card:hover{transform:translateY(-2px);box-shadow:0 10px 24px rgba(31,24,12,.10)}

/* --- Hormati preferensi kurangi gerak --- */
@media(prefers-reduced-motion:reduce){
  .gallery-item,.portal-folder-card,.gallery-image-wrap::before{transition:none}
  .portal-folder-card:hover{transform:none}
}

/* ============================================================
   JUDUL PROJECT: NAMA - KAMPUS, lalu kode booking | tanggal
   ============================================================ */
.portal-heading__meta,
.project-card__meta{
  margin:.35rem 0 0;
  color:var(--muted);
  font-weight:600;
  letter-spacing:.02em;
  /* Lebih kecil dari judul, tetapi WAJIB lebih besar daripada label
     "Foto tersedia / Dipilih / Submission / Deadline" (.75rem) agar
     hierarkinya terbaca benar. */
  font-size:.95rem;
  line-height:1.4;
  overflow-wrap:anywhere;
}
.project-card__title{
  margin:.25rem 0 0;
  overflow-wrap:anywhere;
  text-wrap:balance;
}
/* Label dl dibuat sedikit lebih kecil supaya jarak hierarkinya jelas. */
.project-card dt{font-size:.72rem}

/* ============================================================
   KOLOM GALERI: 3-4 di ponsel, 4-5 di tablet
   Sebelumnya 2 kolom di ponsel dan 4 di tablet, sehingga thumbnail
   terlalu besar dan klien harus banyak menggulir.
   ============================================================ */
/* Tablet: 5 kolom pada tablet lebar, 4 pada tablet sempit. */
@media(max-width:1050px){
  .client-gallery{grid-template-columns:repeat(5,minmax(0,1fr));gap:10px}
}
@media(max-width:860px){
  .client-gallery{grid-template-columns:repeat(4,minmax(0,1fr));gap:9px}
}
/* Ponsel: 4 kolom pada layar lebar, 3 pada layar sempit. */
@media(max-width:700px){
  .client-gallery{grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;--masonry-gap:8px}
}
@media(max-width:420px){
  .client-gallery{grid-template-columns:repeat(3,minmax(0,1fr));gap:7px;--masonry-gap:7px}
}

/* Thumbnail mengecil, jadi kontrolnya ikut dirapikan agar tidak menumpuk
   maupun menutupi foto. Label teks disembunyikan, ikonnya tetap. */
@media(max-width:860px){
  .gallery-item{padding:3px;border-radius:10px}
  .gallery-image-wrap{border-radius:8px}
  /* Thumbnail hanya ~109px di 3 kolom. Label "Pilih" yang ikut tampil membuat
     kotaknya selebar 82px dan menabrak tombol unduh di sudut seberangnya.
     Teksnya disembunyikan sebagai elemen (bukan lewat font-size:0 yang mudah
     dikalahkan aturan lain); kotak centangnya sendiri tetap terlihat, dan
     nama aksesibelnya tetap ada lewat aria-label. */
  .gallery-item .selection-check{
    left:4px;bottom:4px;padding:4px;gap:0;
    min-height:0;width:auto;border-radius:8px;
  }
  .gallery-item .selection-check span{
    position:absolute;width:1px;height:1px;overflow:hidden;
    clip:rect(1px,1px,1px,1px);white-space:nowrap;
  }
  .gallery-item .selection-check input[type=checkbox]{width:18px;height:18px;margin:0}
  .gallery-view-button,.gallery-download-button{
    min-width:32px;min-height:32px;width:32px;height:32px;padding:0
  }
  .gallery-view-button svg,.gallery-download-button svg{width:15px;height:15px}
  /* Nama berkas disembunyikan di kolom sempit: pasti terpotong dan
     tidak membantu klien memilih foto. Tetap ada untuk pembaca layar. */
  .gallery-item .filename,.gallery-item .gallery-filename{
    position:absolute;width:1px;height:1px;padding:0;margin:0;border:0;
    overflow:hidden;clip:rect(1px,1px,1px,1px);white-space:nowrap
  }
}

/* ============================================================
   Tajuk kelompok galeri (sesi / lokasi).

   .client-gallery adalah CSS grid, jadi tajuk WAJIB merentang penuh
   satu baris — tanpa grid-column ia hanya mengisi satu sel foto.
   Namanya diambil apa adanya dari nama folder Google Drive.
   ============================================================ */
.gallery-group-heading{
  grid-column:1 / -1;
  margin:22px 0 2px;
  padding-bottom:8px;
  border-bottom:1px solid var(--line);
  color:var(--gold);
  font-size:.82rem;
  font-weight:800;
  letter-spacing:.12em;
  text-transform:uppercase;
}
.gallery-group-heading:first-child{margin-top:0}
@media(max-width:700px){
  .gallery-group-heading{margin:16px 0 2px;font-size:.76rem;letter-spacing:.1em}
}

/* ---- Kolom password dengan ikon mata di ujung kanan ---- */
.portal-password-field{position:relative;display:block}
.portal-password-field input{width:100%;padding-right:48px!important}
.portal-eye{
  position:absolute;top:50%;right:6px;transform:translateY(-50%);
  width:38px;height:38px;display:grid;place-items:center;
  border:0;border-radius:8px;background:transparent;cursor:pointer;color:var(--muted);
  padding:0;
}
.portal-eye:hover{color:var(--ink)}
.portal-eye:focus-visible{outline:3px solid var(--gold-light);outline-offset:2px}
/* Ikon digambar CSS agar tidak menambah permintaan berkas. Mata terbuka: */
.portal-eye::before{
  content:"";width:22px;height:22px;display:block;
  background:currentColor;
  -webkit-mask:no-repeat center/22px 22px;mask:no-repeat center/22px 22px;
  -webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><path d='M2.5 12S6 5.5 12 5.5 21.5 12 21.5 12 18 18.5 12 18.5 2.5 12 2.5 12Z'/><circle cx='12' cy='12' r='3.2'/></svg>");
  mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><path d='M2.5 12S6 5.5 12 5.5 21.5 12 21.5 12 18 18.5 12 18.5 2.5 12 2.5 12Z'/><circle cx='12' cy='12' r='3.2'/></svg>");
}
/* Mata tercoret saat password sedang diperlihatkan. */
.portal-eye.is-shown::before{
  -webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><path d='M2.5 12S6 5.5 12 5.5 21.5 12 21.5 12 18 18.5 12 18.5 2.5 12 2.5 12Z'/><circle cx='12' cy='12' r='3.2'/><path d='M4 20 20 4'/></svg>");
  mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><path d='M2.5 12S6 5.5 12 5.5 21.5 12 21.5 12 18 18.5 12 18.5 2.5 12 2.5 12Z'/><circle cx='12' cy='12' r='3.2'/><path d='M4 20 20 4'/></svg>");
}
.portal-checkbox-row{display:flex;align-items:center;gap:10px;min-height:44px;cursor:pointer;font-weight:600}
.portal-checkbox-row input[type=checkbox]{width:20px;height:20px;flex:0 0 20px;accent-color:var(--gold);margin:0}
