이 문서는 다음 유지보수자를 위한 인수인계 기록이다.

이번 패스의 핵심은 공지/알림의 버튼 계층을 3개로 고정하고, 닫기/숨기기 동작을 실제로 동작하게 만들면서, 문구·숨김 시간·디자인 토큰의 중앙 통제 경로를 명확히 분리한 것이다.

이번 추가 패스의 핵심 요약

1) 공지의 실제 중앙 원본은 theme data 에 둔다

파일:

  • themes/(0000-0000-0000-0001)/data/40-communication/announcement/_index.toml
  • themes/(0000-0000-0000-0001)/data/40-communication/announcement/ko.toml
  • themes/(0000-0000-0000-0001)/data/40-communication/announcement/en.toml
  • themes/(0000-0000-0000-0001)/data/40-communication/announcement/jp.toml
  • themes/(0000-0000-0000-0001)/data/40-communication/announcement/cn.toml

변경 내용:

  • 공지의 전역 규칙과 구조는 base data 파일에서 관리한다.
  • 언어별 버튼 문구, 제목, 본문, 이미지 대체텍스트, CTA 문구는 언어별 오버라이드 파일에서 관리한다.
  • ui 블록에 공지 특수문자(), 상세보기, 닫기, 24시간 동안 숨기기의 기본값을 둬서, 문구를 한 파일 계층에서 바로 제어할 수 있게 했다.
  • 숨김 시간은 snoozeHours / defaultSnoozeHours 로 분리해서, 24시간 고정이 아니라 운영자가 원하는 시간으로 바꿀 수 있게 했다.

중요한 이유:

  • 공지 문구를 i18n YAML 에만 분산시키면 운영자가 실제 원본 경로를 찾기 어렵다.
  • 버튼 텍스트와 숨김 시간은 운영 정책이므로 theme data 에 있어야 추적과 변경이 쉽다.
  • 전역 구조와 로케일 문구를 분리하면 다국어 확장 시에도 파일 충돌이 줄어든다.

2) 설정 정규화는 theme/announcement-config.html 에서만 처리한다

파일:

  • themes/(0000-0000-0000-0001)/layouts/partials/theme/announcement-config.html
  • themes/(0000-0000-0000-0001)/layouts/partials/theme/settings.html

변경 내용:

  • 공지 아이템을 렌더러가 바로 읽지 않고, 정규화된 중간 구조로 바꾸는 단계를 분리했다.
  • ctaLabeldetailLabel 로도 해석되도록 정리해서, 기존 데이터와 새 데이터가 같이 공존할 수 있게 했다.
  • secondary CTA 는 더 이상 렌더링하지 않도록 구조를 정리했다.
  • dismissHourssnoozeHours 를 모두 읽게 해서, 기존 값과 새 값이 같이 동작하도록 호환성을 남겼다.
  • dismissMode 가 없으면 session, hours, persistent 중 적절한 값으로 계산한다.
  • 렌더링에 불필요한 중복 계산을 줄여서 settings 파셜이 비대해지지 않게 했다.

중요한 이유:

  • 설정 계산과 렌더링을 분리해야 코드가 스파게티가 되지 않는다.
  • 기존 키를 바로 버리지 않고 새 키를 흡수하면, 기존 콘텐츠가 한 번에 깨지지 않는다.
  • 중앙 통제 포인트를 한 파일로 모아두면 나중에 공지 유형이 늘어나도 확장 위치가 분명하다.

3) 버튼 계층은 상세보기 → 닫기 → 24시간 동안 숨기기 순서로 정리했다

파일:

  • themes/(0000-0000-0000-0001)/layouts/partials/theme/announcement.html
  • themes/(0000-0000-0000-0001)/assets/css/common/announcement.css
  • themes/(0000-0000-0000-0001)/assets/css/core/theme-vars/80-announcement.css

변경 내용:

  • 공지/알림은 이제 3개 버튼만 다룬다.
  • 상세보기 는 가장 강한 primary CTA 로 배치했다.
  • 닫기 는 일반 버튼 형태로, 24시간 동안 숨기기 는 텍스트형 작은 버튼으로 분리했다.
  • 버튼 순서와 시각적 우선순위를 함께 맞춰서, 디바이스가 달라도 읽는 순서가 자연스럽게 이어지게 했다.
  • 모바일에서는 상세보기닫기 가 넓게 눌리도록 유지하고, 숨기기 버튼은 작은 텍스트형 링크처럼 보이게 조정했다.
  • 공지의 특수문자는 로 통일했다.

중요한 이유:

  • 공지는 읽기용 정보가 아니라 행동 유도 요소이므로, 버튼 위계가 모호하면 사용자가 무엇을 먼저 눌러야 하는지 헷갈린다.
  • 텍스트형 작은 숨김 버튼은 실수로 누를 가능성을 줄이고, 닫기와 시간 제한 숨김을 시각적으로 구분한다.
  • 로 통일하면 전역 공지의 시그널이 흔들리지 않는다.

4) 닫기 / 숨김 동작은 실제 저장 로직으로 분리했다

파일:

  • themes/(0000-0000-0000-0001)/layouts/partials/theme/announcement.html
  • themes/(0000-0000-0000-0001)/assets/js/04-composition-layer/cross-cutting-composition/announcement.js

변경 내용:

  • 닫기 는 sessionStorage 를 사용해 현재 세션 동안만 숨긴다.
  • 숨기기 는 localStorage + TTL 을 사용해 지정 시간 동안 다시 보이지 않게 한다.
  • 저장 키는 공지별 storageKey 를 기준으로 분리해서, 서로 다른 공지가 상태를 공유하지 않게 했다.
  • 버튼 클릭은 이벤트 위임 방식으로 처리해서 모달/배너/인라인 구조가 달라도 같은 동작을 쓴다.
  • snoozeHours 값이 바뀌면 같은 공지라도 TTL 정책이 달라질 수 있게 설계했다.

중요한 이유:

  • 닫기와 시간 제한 숨김은 완전히 다른 의도다.
  • 저장 없이 단순히 화면만 감추면 새로고침 때 다시 뜨는 문제가 생긴다.
  • 이벤트 위임은 렌더링 방식이 늘어나도 JS 를 다시 복사하지 않게 해준다.

5) 디자인 토큰은 theme-vars 계층만 수정했다

파일:

  • themes/(0000-0000-0000-0001)/assets/css/core/theme-vars/80-announcement.css
  • themes/(0000-0000-0000-0001)/assets/css/core/design-tokens.css

변경 내용:

  • 공지 관련 색상, 간격, 타이포그래피, 버튼 밀도, 숨김 버튼의 텍스트형 토큰을 전역 변수로 분리했다.
  • 반응형 구간에서 데스크톱 / 태블릿 / 모바일의 버튼 밀도와 폭을 다르게 볼 수 있도록 토큰을 조정했다.
  • 모든 공지 유형의 심볼 토큰을 로 통일했다.
  • 실제 렌더러는 CSS 토큰만 소비하고, 값 자체는 theme-vars 계층에서 바꾸도록 유지했다.

중요한 이유:

  • 디자인 값이 페이지별 하드코딩으로 흩어지면 업그레이드가 불가능해진다.
  • theme-vars 는 전체 UI 시스템의 중앙 제어판이어야 한다.
  • 공지처럼 작은 컴포넌트도 토큰이 분리되어 있어야 나중에 확장할 때 영향 범위를 통제할 수 있다.

현재 트리 구조

config/
└── _default/
    ├── hugo.toml
    ├── params.toml
    ├── params/
    │   ├── _index.toml   # 경로 안내용 주석 파일
    │   └── cta.toml
    └── languages/
        ├── languages.ko.toml
        ├── languages.en.toml
        ├── languages.jp.toml
        └── languages.cn.toml

themes/
└── (0000-0000-0000-0001)/
    ├── assets/
    │   └── css/
    │       ├── common/
    │       │   └── announcement.css
    │       ├── core/
    │       │   └── theme-vars/
    │       │       └── 80-announcement.css
    │       └── js/
    │           └── common/
    │               └── announcement.js
    ├── data/
    │   ├── _index.toml
    │   └── announcement/
    │       ├── ko.toml
    │       ├── en.toml
    │       ├── jp.toml
    │       └── cn.toml
    └── layouts/
        └── partials/
            └── theme/
                ├── announcement-config.html
                ├── announcement.html
                └── settings.html

운영 메모

  • config/_default/params/_index.toml 은 실제 값 저장소가 아니라 경로 설명서다.
  • 버튼 문구를 바꾸고 싶으면 themes/(0000-0000-0000-0001)/data/40-communication/announcement/<lang>.toml 를 먼저 본다.
  • 숨김 시간을 바꾸고 싶으면 ui.snoozeHours 또는 개별 item 의 snoozeHours 를 본다.
  • 공지의 ctaHref 가 없으면 상세보기 버튼은 렌더링하지 않는다.
  • 닫기24시간 동안 숨기기 는 항상 서로 다른 저장 방식으로 처리해야 한다.
  • snoozeHours 를 변경했다면 문구도 함께 점검해라. 버튼 문구는 운영 정책이므로 시간과 어긋나면 UX 가 흔들린다.
  • storageKey 는 공지별로 고유해야 한다. 같은 키를 여러 공지에 재사용하면 숨김 상태가 섞인다.
  • 신규 언어를 추가할 때는 data/40-communication/announcement/<lang>.tomli18n/<lang>.yaml 의 책임을 분리해서 정리한다.

검증 기준

  • 전역 공지가 모든 페이지에서 노출되는가
  • 섹션 전용 공지가 scope 에 맞는 페이지에서만 노출되는가
  • 상세보기, 닫기, 24시간 동안 숨기기 가 각각 다른 시각적 위계를 가지는가
  • 닫기 는 현재 세션에서만 숨겨지는가
  • 숨기기 는 지정 시간 동안 다시 보이지 않는가
  • 모바일에서 버튼이 겹치거나 잘려 보이지 않는가
  • 공지 심볼이 로 통일되어 있는가
  • theme-vars 만 수정해도 전체 공지 톤이 일괄적으로 바뀌는가

이 로그는 “무엇을 수정했는가"보다 “어디를 바꾸면 전체가 일괄로 바뀌는가"를 남기기 위한 문서다. 다음 변경에서도 같은 구조를 유지하면 유지보수가 훨씬 단순해진다.

이번 추가 패스: 전역 활성화와 스코프 정규화

이번 수정은 공지/알림을 한 번에 점검할 수 있도록 모든 배너를 전역 활성화하고, 배너별 구조를 동일한 형식으로 맞춘 정리다.

핵심 변경

  • themes/(0000-0000-0000-0001)/data/40-communication/announcement/_index.tomlscopeDefaults 를 두고, 각 item 이 같은 구조를 따르도록 정리했다.
  • languages / kinds / sections / pathPrefixes / taxonomies / terms["*"] 를 와일드카드로 해석하도록 통일했다.
  • storageKey 는 비워 두어도 동작하도록 바꿔, 공지별 자동 키 생성이 가능하게 했다.
  • priority 는 큰 숫자가 먼저 노출되는 정렬 힌트로 정리했고, 같은 값일 때도 결과가 흔들리지 않도록 정렬 키를 별도로 만들었다.
  • dismissMode 는 close 버튼의 저장 정책을 뜻하고, 기본값은 session 으로 두었다.
  • snoozeHours24시간 동안 숨기기 같은 시간 제한 숨김에만 사용한다.

닫기 버튼 점검 결과

  • 클릭 이벤트는 캡처 단계에서도 받도록 바꿔서, 상위 요소의 이벤트 차단에 덜 영향을 받게 했다.
  • close 동작은 session / persistent / hours 중 설정값에 맞춰 저장되도록 분리했다.
  • storage 실패가 나더라도 숨김 자체는 계속 수행되도록 유지했다.

레이아웃 점검 결과

  • CTA 와 닫기 버튼은 데스크톱에서 내용 폭에 맞게 정렬하고, 모바일에서만 100% 폭으로 확장한다.
  • footer 와 dismiss 영역의 폭, 정렬, 간격을 theme-vars 토큰으로 분리했다.
  • 버튼 위치는 CSS 하드코딩이 아니라 theme-vars/80-announcement.css 의 토큰으로 조절한다.

확인해야 할 파일 트리

config/_default/params/_index.toml

themes/(0000-0000-0000-0001)/
├─ data/
│  ├─ _index.toml
│  └─ announcement/
│     ├─ ko.toml
│     ├─ en.toml
│     ├─ jp.toml
│     └─ cn.toml
├─ layouts/partials/theme/
│  ├─ announcement-config.html
│  └─ announcement.html
├─ assets/css/common/
│  └─ announcement.css
├─ assets/css/core/theme-vars/
│  └─ 80-announcement.css
└─ assets/js/04-composition-layer/cross-cutting-composition/
   └─ announcement.js

운영 메모

  • 전역 배너를 모두 보려면 base data 의 enabled = true 와 각 item 의 scope wildcard 유지가 핵심이다.
  • 특정 섹션 전용 배너가 필요할 때만 scope 를 좁힌다.
  • storageKey 는 필수가 아니므로, 안정적인 닫기 상태가 꼭 필요할 때만 명시한다.
  • announcementProfile 같은 페이지 단위 분기는 앞으로도 가능하지만, 기본값은 전역 노출이다.

10. 이번 추가 패스: 닫기 동작과 우선순위 규칙 재정리

이번 패스에서는 공지/알림이 “보이기만 하는 상태"가 아니라, 실제로 닫히고, 실제로 숨겨지고, 실제로 순서가 예측 가능하게 보이도록 다시 정리했다.

이번에 바뀐 핵심

  • priority 는 숫자가 낮을수록 먼저 보이도록 바꿨다.
  • itemLimit 을 우선 키로 두고, maxItems 는 하위 호환용 별칭으로 남겼다.
  • itemLimit = 0 또는 미설정은 “제한 없음"으로 해석한다.
  • 닫기 버튼은 sessionStorage 기준으로 현재 세션 동안만 숨긴다.
  • 24시간 동안 숨기기 버튼은 localStorage TTL 로 동작한다.
  • 버튼 클릭은 개별 버튼에 직접 바인딩해서, 이벤트 위임만 의존하던 구조보다 더 안정적으로 만들었다.
  • 숨김 처리에서는 hidden, aria-hidden, inert, display:none 을 함께 적용해서 dialog/section 모두에서 확실하게 사라지도록 했다.

왜 이 수정이 필요한가

  • 기존 구현은 기능이 있더라도 실제 클릭 흐름에서 닫힘 상태가 확실하게 반영되지 않을 가능성이 있었다.
  • priority 를 큰 숫자 우선으로 읽으면 운영자가 1, 2, 3 순서로 생각하기 어렵다.
  • maxItems = 0 이 제한 없음으로 보이는 방식은 동작은 가능하지만 직관성이 떨어진다.
  • 지금 구조는 “값이 없으면 기본값”, “양수만 제한”, “작은 숫자가 먼저"라는 일반적인 운영 패턴에 더 가깝다.

이번 패스에서 확인해야 할 포인트

  • 버튼을 눌렀을 때 announcement 요소가 즉시 사라지는가
  • 새로고침 후 session / persistent / hours 정책이 각각 제대로 남는가
  • priority 가 낮은 값부터 위로 올라오는가
  • itemLimit 이 있으면 개수 제한이 실제로 걸리는가
  • 언어별 override 파일이 문구만 덮어쓰고 구조는 유지하는가

파일 영향 범위

config/_default/params/_index.toml
themes/(0000-0000-0000-0001)/data/40-communication/announcement/_index.toml
themes/(0000-0000-0000-0001)/data/40-communication/announcement/ko.toml
themes/(0000-0000-0000-0001)/layouts/partials/theme/announcement-config.html
themes/(0000-0000-0000-0001)/layouts/partials/theme/announcement.html
themes/(0000-0000-0000-0001)/assets/js/04-composition-layer/cross-cutting-composition/announcement.js
themes/(0000-0000-0000-0001)/assets/css/common/announcement.css
themes/(0000-0000-0000-0001)/layouts/partials/theme/settings.html