/* ============================================================
   guest.css — 비로그인(게스트) 상태 전용 규칙
   index.html 에서만 로드한다. history/admin/login 은 영향을 받지 않는다.

   [왜 style.css 에 넣지 않았는가]
   style.css 는 index · history · admin 이 함께 쓰는 3,100줄대(현재 3,105줄) 공용 파일이라
   한 줄만 바꿔도 세 페이지가 같이 흔들린다. 그래서 공용 파일은 읽기 전용으로 두고,
   이 화면에서만 필요한 규격은 여기에 복제해 둔다.

   [표시 전환 규약]
   이 파일의 요소들은 전부 기본 hidden 이고 JS(auth.js / app.js)가 로그인
   상태를 확정한 뒤에만 hidden 을 푼다. 그래서 각 규칙에는 반드시
   `[hidden] { display: none; }` 짝을 둔다 — 클래스가 display 를 선언하는
   순간 UA 기본 스타일 `[hidden]{display:none}` (특이도 0,0,1) 을 이겨 버려
   hidden 이 무시되기 때문이다(클래스 0,1,0 > UA 규칙).
   ============================================================ */

/* ------------------------------------------------------------
   1. 상단바 로그인 진입점 (.guest-login)

   [왜 .btn--primary 를 쓰지 않는가]
   .topbar__right 는 --surface-soft 배경 + 테두리를 가진 pill 그룹이다.
   그 안에 그라디언트/그림자를 가진 .btn--primary 를 넣으면 배경이 이중으로
   겹치고 그림자가 그룹 밖으로 새어 나온다(랜딩 헤더에서 이미 겪은 회귀).
   규격 출처는 style.css 의 .topnav__item(현재 396번째 줄) 이다 — 여기 값들은
   그 규칙을 복제해 온 것이다. min-height 38px 는 같은 그룹 안
   .user-chip(36px)/.theme-toggle(38px) 와 시각 높이를 맞춘 값이다.
   (과거 landing.css 의 .landing-login 도 같은 원본에서 복제된 사본이었으나
    랜딩 화면과 함께 제거됐다. 남은 사본은 이 파일 하나뿐이다.)
   ------------------------------------------------------------ */
.guest-login {
    display: inline-flex;
    align-items: center;
    padding: 0 12px;
    min-height: 38px;
    border-radius: var(--radius-full);
    background: var(--accent-soft);
    color: var(--text-primary);
    text-decoration: none;
    font-size: 0.84rem;
    font-weight: 700;
    white-space: nowrap;
    position: relative;
    transition: background-color var(--transition-base), color var(--transition-base);
}
.guest-login[hidden] { display: none; }

/* 터치 히트영역 44px 확보(시각 높이는 38px 유지).
   .topnav__item::before / .theme-toggle::before 와 동일한 관례다. */
.guest-login::before {
    content: '';
    position: absolute;
    inset: -3px 0;
    min-height: 44px;
}

/* 🔴 반드시 있어야 한다 — style.css:1969 의 포커스 링 목록은 셀렉터를 일일이
   나열하는 방식이라, 그 목록에 없는 새 클래스는 키보드 포커스 표시가 조용히
   사라진다(마우스 화면에는 아무 변화가 없어 육안 점검으로 발견되지 않는다).
   토큰은 style.css 의 --focus-ring 을 그대로 써서 라이트/다크 자동 대응. */
.guest-login:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}

/* hover 는 포인터가 있는 환경에서만(터치에서는 탭 후 잔류한다).
   translateY 를 쓰지 않는 이유: pill 그룹 안에서 위로 밀면 윤곽이 그룹 밖으로
   새어 나와 헤더가 어긋나 보인다. 배경색만 바꾼다. */
@media (hover: hover) {
    .guest-login:hover { background: var(--bg-secondary); }
}
.guest-login:active { transform: scale(0.96); }

/* ------------------------------------------------------------
   2. 비로그인 안내 배너 (.guest-banner)

   .controls-panel 직속이지만 .section 이 "아니다".
   🔴 모바일 위저드(app.js initMobileWizard)는 .controls-panel 직속 .section 을
      "위치 기준으로 앞 5개" 집어 스텝으로 쓴다. 여기에 .section 을 붙이면
      스텝 구성이 통째로 어긋나(6개 중 앞 5개) 위저드가 조용히 오작동한다.
   .section 이 아니라서 `.controls-panel.is-wizard > .section:not(.is-current)`
   숨김 규칙에도 걸리지 않는다 → 모든 스텝에서 계속 보인다. 이것이 목적이다:
   마지막 스텝까지 가서야 "생성하려면 로그인" 을 알게 되는 헛수고를 막는다.
   ------------------------------------------------------------ */
.guest-banner {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
    margin-bottom: var(--space-4);
    padding: 14px 16px;
    border-radius: var(--radius-lg);
    background: var(--accent-soft);
    border: 1px solid var(--border-color);
}
.guest-banner[hidden] { display: none; }

.guest-banner__text {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
    flex: 1 1 220px;
}
.guest-banner__title {
    font-size: var(--font-size-body);
    font-weight: 700;
    color: var(--text-primary);
}
.guest-banner__desc {
    font-size: var(--font-size-small);
    line-height: 1.55;
    color: var(--text-secondary);
}

/* ------------------------------------------------------------
   3. 잠긴 컨트롤의 사유 문구 (.guest-lock-note)

   🔴 공용 notice 슬롯(#uploadNotice / #generateNotice)을 쓰지 않는 이유:
      · #uploadNotice 는 HEIC 변환 진행 카운터가 textContent 대조로 소유권을
        확인하며 쓰는 자리다. 다른 문장이 들어오면 카운터가 영구히 침묵한다.
      · #generateNotice 는 상품 정보 저장 안내(placeProductInfoNotice)와
        생성 게이트가 번갈아 쓰는 자리라, 상시 표시가 필요한 문구를 두면
        서로 지운다.
      둘 다 "잠깐 떴다 회수되는" 자리이고, 여기 문구는 로그인 전까지 계속
      떠 있어야 한다 → 전용 자리를 따로 둔다.
   ------------------------------------------------------------ */
.guest-lock-note {
    margin: 10px 0 0;
    font-size: var(--font-size-small);
    line-height: 1.55;
    color: var(--text-secondary);
}
.guest-lock-note[hidden] { display: none; }

/* ------------------------------------------------------------
   4. 잠긴 탭의 비활성 표현 (안전핀)

   style.css 에는 .btn:disabled(opacity 0.55) 와 .media-seg-btn:disabled 는
   있어도 .tab:disabled 가 없다. 비활성인데 화면이 그대로면 "고장났다"로
   읽히므로 같은 0.55 로 맞춘다(비활성 표현의 일관성 — style.css:761 기준).

   🔴 지금은 어느 코드도 .tab 에 disabled 를 세우지 않는다 — URL 탭 잠금이
      disabled 에서 .is-guest-locked(아래 5번)로 옮겨졌기 때문이다.
      그 이유는 app.js applyGuestLocks() C2 주석에 있다: 비활성 버튼은 click
      이벤트가 발생하지 않아 "왜 안 되는지" 를 띄울 방법이 없다.
      그래도 이 규칙은 남긴다 — 나중에 누가 다시 .tab 에 disabled 를 세우면
      style.css 에 대응 규격이 없어 "안 눌리는데 멀쩡해 보이는" 탭이 된다.
   ------------------------------------------------------------ */
.tab:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* ------------------------------------------------------------
   5. "보이되 잠긴" 컨트롤 (.is-guest-locked)

   대상: 상단바 '이력'(#historyLink) · '내 이미지로 스타일 만들기'(#styleModeImageBtn)
        · 'URL로 가져오기' 탭(#tabUrlBtn).
   셋 다 예전에는 감추거나(이력·스타일) 비활성으로 세웠지만(URL 탭), 감추면
   그런 기능이 있다는 사실조차 전달되지 않아 로그인할 이유가 생기지 않고,
   비활성은 click 이벤트가 발생하지 않아 사유를 띄울 수조차 없다.
   그래서 보여 주되 "지금은 눌러도 진행되지 않는다" 가 한눈에 보여야 한다.
   실제 차단과 사유 안내는 JS 가 한다
   (auth.js lockGuestHistoryLink · app.js guardGuestLockedClick).

   🔴 잠금 표시를 disabled / hidden 이 아니라 "클래스"로 하는 이유:
      두 속성은 각각 다른 주인이 있다 — #styleModeImageBtn 의 disabled 는
      가용성 로직(app.js applyStyleModeAvailability)이 스타일 목록 응답이
      도착할 때마다 다시 칠한다. 클래스는 그 로직들이 만지지 않는 유일한
      표면이라, 응답이 늦게 와도 이 표시가 벗겨지지 않는다.

   🔴 id 셀렉터(1,1,0)로 쓰는 이유 — 아래 규격들을 확실히 이겨야 한다:
      · .media-seg-btn:disabled (0,2,0) : opacity 0.45 를 선언한다.
      · .topnav__item.is-active (0,2,0) : 배경/색을 선언한다.
      🔴 .topnav 계열 "클래스" 셀렉터를 새로 만들지 않는다 — 그 규격은
         style.css 의 소유이고, 여기서 복제하면 두 곳이 어긋난다.

   opacity 0.55 는 style.css:761 .btn:disabled / :912 .upload-drop.is-locked 와
   같은 값이다(화면 전체에서 비활성 표현을 하나로 유지).
   ------------------------------------------------------------ */
#historyLink.is-guest-locked,
#styleModeImageBtn.is-guest-locked,
#tabUrlBtn.is-guest-locked {
    opacity: 0.55;
    cursor: not-allowed;
}

/* 🔴 hover 반응도 함께 꺼야 한다. 안 끄면 잠긴 컨트롤이 손댈 때만 활성처럼
   되살아나 잠금 표시가 무효가 된다(.upload-drop.is-locked 와 같은 근거).
   덮어야 할 규칙: style.css 의 .topnav__item:not(.is-active):hover (0,3,0) ·
   .media-seg-btn:not(.is-active):hover (0,3,0) · .tab:not(.is-active):hover
   (0,3,0) — 아래는 (1,2,0) 이라 이긴다. */
@media (hover: hover) {
    #historyLink.is-guest-locked:hover {
        background: transparent;
        color: var(--text-secondary);
    }
    #styleModeImageBtn.is-guest-locked:hover { color: var(--text-secondary); }
    #tabUrlBtn.is-guest-locked:hover { color: var(--text-secondary); }
}

/* ------------------------------------------------------------
   5-1. 잠금 표식 (자물쇠)

   🔴 왜 필요한가 — 위의 잠금 표현은 `opacity: .55` 와 `cursor: not-allowed`
      둘뿐이다. 그런데 터치 기기에는 커서가 없다. 즉 휴대폰 사용자에게는
      실질적으로 "조금 흐리다" 하나만 남는데, 그것만으로는 "잠김"과 "그냥
      연한 보조 버튼"이 구분되지 않는다. 눌러 보기 전에도 알 수 있어야 한다.

   🔴 왜 이 정도만 하는가 — 잠긴 곳이 3개다. 배지·테두리·문구까지 붙이면
      첫 화면이 자물쇠 투성이가 되어 "이 서비스는 되는 게 없다"로 읽힌다
      (로그인을 유도하려다 이탈시키는 역효과). 그래서 문자 크기(0.85em)의
      단색 표식 하나로 끝낸다. 부모가 이미 opacity .55 라 표식도 같이
      연해져 저절로 배경으로 물러난다.
      🔴 생성 버튼(C1)에는 붙이지 않는다 — 그쪽은 화면에서 가장 큰 주
         CTA 이고 바로 옆에 상시 사유 문구(#guestGenerateNote)가 있다.

   🔴 새 이미지 파일을 만들지 않는다(요청 0건 유지). 인라인 SVG 를 mask 로
      깔고 색은 background-color: currentColor 로 준다 → 라이트/다크,
      hover, 활성/비활성 어떤 상태에서도 글자색을 그대로 따라간다.
      (background-image 로 넣으면 SVG 안에 색을 박아야 해서 다크 모드에서
       검은 자물쇠가 그대로 남는다.)

   🔴 content: '' + mask 인 이유(문자·이모지를 안 쓰는 이유):
      · 🔒 이모지는 OS 마다 크기·색·여백이 제각각이고 컬러라서 위 톤 통일이 깨진다.
      · CSS content 의 "문자"는 일부 스크린리더가 읽어 버린다. 여기서 잠김은
        이미 aria-disabled 로 전달되므로, 표식은 순수 장식이어야 중복 안내가 없다.

   🔴 @supports 로 감싼다. mask 를 모르는 브라우저에서 이 규칙이 그대로 적용되면
      마스크 없이 background-color 만 남아 "정체불명의 검은 사각형"이 된다.
      지원하지 않으면 표식이 없을 뿐, 흐림 표현은 그대로 남는다(안전한 열화).

   ::after 를 쓰는 이유: #historyLink 는 .topnav__item::before 가 이미
      터치 히트영역(44px) 확보에 쓰이고 있다. 덮어쓰면 상단바 링크의 탭
      영역이 줄어든다.
   ------------------------------------------------------------ */
@supports ((-webkit-mask-image: none) or (mask-image: none)) {
    #historyLink.is-guest-locked::after,
    #styleModeImageBtn.is-guest-locked::after,
    #tabUrlBtn.is-guest-locked::after {
        content: '';
        display: inline-block;
        flex: none;              /* .topnav__item 은 inline-flex → 표식이 늘어나지 않게 */
        width: 0.85em;
        height: 0.85em;
        margin-left: 5px;
        vertical-align: -0.11em; /* 글자 baseline 에 맞춘다(탭·세그먼트는 인라인 흐름) */
        background-color: currentColor;
        -webkit-mask-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 10.5V7a4 4 0 0 1 8 0v3.5' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round'/%3E%3Crect x='4' y='10.5' width='16' height='10.5' rx='2.5' fill='black'/%3E%3C/svg%3E");
        mask-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 10.5V7a4 4 0 0 1 8 0v3.5' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round'/%3E%3Crect x='4' y='10.5' width='16' height='10.5' rx='2.5' fill='black'/%3E%3C/svg%3E");
        -webkit-mask-repeat: no-repeat;
        mask-repeat: no-repeat;
        -webkit-mask-position: center;
        mask-position: center;
        -webkit-mask-size: contain;
        mask-size: contain;
    }

    /* .topnav__item 은 flex 컨테이너이고 gap: 6px 가 이미 있다 → margin 을 더하면 두 배가 된다. */
    #historyLink.is-guest-locked::after { margin-left: 0; }
}

/* 🔴 아래 두 [hidden] 짝은 남겨 둔다. 지금은 어느 코드도 이 요소들에 hidden 을
   세우지 않지만(잠금이 클래스로 바뀌었다), 두 요소 모두 다른 파일(style.css)에서
   display 를 선언받는다 — 나중에 누군가 hidden 을 세우는 순간 그 선언이 UA 기본
   [hidden]{display:none} (0,0,1) 을 이겨 "hidden 인데 보이는" 상태가 된다.
   이 파일 머리말의 표시 전환 규약을 그대로 유지하는 안전핀이다. */
#styleModeImageBtn[hidden] { display: none; }
#historyLink[hidden] { display: none; }
