commit edacb0814155f8ec8375ef8754f006927f5499f0 Author: y2keui Date: Wed Jun 24 10:41:31 2026 +0900 feat: build company introduction webpage diff --git a/README.md b/README.md new file mode 100644 index 0000000..c1d1294 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# CompanyIntroduction + +컴트로피 회사소개서 PPTX 내용을 기반으로 만든 정적 웹 소개 페이지입니다. + +## 구성 + +- `index.html`: 페이지 마크업과 회사소개 콘텐츠 +- `styles.css`: 시네마틱 원페이지 UI 스타일 +- `script.js`: 로더, 스크롤 리빌, 모바일 메뉴, 사업 사례 탭 +- `assets/media/`: PPTX에서 추출 및 웹 최적화한 이미지 자산 + +## 실행 + +브라우저에서 `index.html`을 열면 바로 확인할 수 있습니다. diff --git a/assets/media/ai-detection-console.webp b/assets/media/ai-detection-console.webp new file mode 100644 index 0000000..404d53f Binary files /dev/null and b/assets/media/ai-detection-console.webp differ diff --git a/assets/media/ai-distance-result.webp b/assets/media/ai-distance-result.webp new file mode 100644 index 0000000..2c1cbc6 Binary files /dev/null and b/assets/media/ai-distance-result.webp differ diff --git a/assets/media/ai-training-green.webp b/assets/media/ai-training-green.webp new file mode 100644 index 0000000..a424868 Binary files /dev/null and b/assets/media/ai-training-green.webp differ diff --git a/assets/media/client-01-kpga.png b/assets/media/client-01-kpga.png new file mode 100644 index 0000000..8da4eda Binary files /dev/null and b/assets/media/client-01-kpga.png differ diff --git a/assets/media/client-02-ktv.png b/assets/media/client-02-ktv.png new file mode 100644 index 0000000..2b094be Binary files /dev/null and b/assets/media/client-02-ktv.png differ diff --git a/assets/media/client-03-kt-alpha.png b/assets/media/client-03-kt-alpha.png new file mode 100644 index 0000000..98a7451 Binary files /dev/null and b/assets/media/client-03-kt-alpha.png differ diff --git a/assets/media/client-04-sk-store.png b/assets/media/client-04-sk-store.png new file mode 100644 index 0000000..99b38a2 Binary files /dev/null and b/assets/media/client-04-sk-store.png differ diff --git a/assets/media/client-05-wbdg.png b/assets/media/client-05-wbdg.png new file mode 100644 index 0000000..326c7e6 Binary files /dev/null and b/assets/media/client-05-wbdg.png differ diff --git a/assets/media/client-06-ytn.png b/assets/media/client-06-ytn.png new file mode 100644 index 0000000..8e250d0 Binary files /dev/null and b/assets/media/client-06-ytn.png differ diff --git a/assets/media/client-07-maekyung-tv.png b/assets/media/client-07-maekyung-tv.png new file mode 100644 index 0000000..7ddc400 Binary files /dev/null and b/assets/media/client-07-maekyung-tv.png differ diff --git a/assets/media/client-08-yonhapnews-tv.png b/assets/media/client-08-yonhapnews-tv.png new file mode 100644 index 0000000..b459041 Binary files /dev/null and b/assets/media/client-08-yonhapnews-tv.png differ diff --git a/assets/media/client-09-etdaily-tv.png b/assets/media/client-09-etdaily-tv.png new file mode 100644 index 0000000..86b64a7 Binary files /dev/null and b/assets/media/client-09-etdaily-tv.png differ diff --git a/assets/media/client-10-com2us.png b/assets/media/client-10-com2us.png new file mode 100644 index 0000000..8ad1bd3 Binary files /dev/null and b/assets/media/client-10-com2us.png differ diff --git a/assets/media/client-11-tomato-securities.png b/assets/media/client-11-tomato-securities.png new file mode 100644 index 0000000..d4707ae Binary files /dev/null and b/assets/media/client-11-tomato-securities.png differ diff --git a/assets/media/client-12-shinsegae-shopping.png b/assets/media/client-12-shinsegae-shopping.png new file mode 100644 index 0000000..d48da8d Binary files /dev/null and b/assets/media/client-12-shinsegae-shopping.png differ diff --git a/assets/media/client-13-mbc-cni.png b/assets/media/client-13-mbc-cni.png new file mode 100644 index 0000000..22de9e3 Binary files /dev/null and b/assets/media/client-13-mbc-cni.png differ diff --git a/assets/media/client-14-mbc.png b/assets/media/client-14-mbc.png new file mode 100644 index 0000000..29e5fbd Binary files /dev/null and b/assets/media/client-14-mbc.png differ diff --git a/assets/media/client-15-riot-games.png b/assets/media/client-15-riot-games.png new file mode 100644 index 0000000..6b121d8 Binary files /dev/null and b/assets/media/client-15-riot-games.png differ diff --git a/assets/media/client-16-snuh.png b/assets/media/client-16-snuh.png new file mode 100644 index 0000000..b3385f1 Binary files /dev/null and b/assets/media/client-16-snuh.png differ diff --git a/assets/media/digital-network.png b/assets/media/digital-network.png new file mode 100644 index 0000000..a6dd9e1 Binary files /dev/null and b/assets/media/digital-network.png differ diff --git a/assets/media/election-candidate-screen.webp b/assets/media/election-candidate-screen.webp new file mode 100644 index 0000000..d37421f Binary files /dev/null and b/assets/media/election-candidate-screen.webp differ diff --git a/assets/media/election-control-strip.webp b/assets/media/election-control-strip.webp new file mode 100644 index 0000000..334dfe9 Binary files /dev/null and b/assets/media/election-control-strip.webp differ diff --git a/assets/media/election-region-map.webp b/assets/media/election-region-map.webp new file mode 100644 index 0000000..d104579 Binary files /dev/null and b/assets/media/election-region-map.webp differ diff --git a/assets/media/election-seat-map.webp b/assets/media/election-seat-map.webp new file mode 100644 index 0000000..970e370 Binary files /dev/null and b/assets/media/election-seat-map.webp differ diff --git a/assets/media/election-ticker.webp b/assets/media/election-ticker.webp new file mode 100644 index 0000000..90af242 Binary files /dev/null and b/assets/media/election-ticker.webp differ diff --git a/assets/media/finance-chart.webp b/assets/media/finance-chart.webp new file mode 100644 index 0000000..f0cd8ec Binary files /dev/null and b/assets/media/finance-chart.webp differ diff --git a/assets/media/finance-db-console.webp b/assets/media/finance-db-console.webp new file mode 100644 index 0000000..80a841b Binary files /dev/null and b/assets/media/finance-db-console.webp differ diff --git a/assets/media/finance-index.webp b/assets/media/finance-index.webp new file mode 100644 index 0000000..61e5553 Binary files /dev/null and b/assets/media/finance-index.webp differ diff --git a/assets/media/finance-market-share.webp b/assets/media/finance-market-share.webp new file mode 100644 index 0000000..75bc3e8 Binary files /dev/null and b/assets/media/finance-market-share.webp differ diff --git a/assets/media/finance-server-console.webp b/assets/media/finance-server-console.webp new file mode 100644 index 0000000..8072f0e Binary files /dev/null and b/assets/media/finance-server-console.webp differ diff --git a/assets/media/football-scorebug.webp b/assets/media/football-scorebug.webp new file mode 100644 index 0000000..401beaf Binary files /dev/null and b/assets/media/football-scorebug.webp differ diff --git a/assets/media/mobile-live-talk.webp b/assets/media/mobile-live-talk.webp new file mode 100644 index 0000000..7789be3 Binary files /dev/null and b/assets/media/mobile-live-talk.webp differ diff --git a/assets/media/shopping-automation.webp b/assets/media/shopping-automation.webp new file mode 100644 index 0000000..71d3589 Binary files /dev/null and b/assets/media/shopping-automation.webp differ diff --git a/assets/media/shopping-control-dashboard.webp b/assets/media/shopping-control-dashboard.webp new file mode 100644 index 0000000..313bc29 Binary files /dev/null and b/assets/media/shopping-control-dashboard.webp differ diff --git a/assets/media/shopping-live-output.webp b/assets/media/shopping-live-output.webp new file mode 100644 index 0000000..b9c416d Binary files /dev/null and b/assets/media/shopping-live-output.webp differ diff --git a/assets/media/shopping-schedule-console.webp b/assets/media/shopping-schedule-console.webp new file mode 100644 index 0000000..01dcba1 Binary files /dev/null and b/assets/media/shopping-schedule-console.webp differ diff --git a/assets/media/sports-game-result.webp b/assets/media/sports-game-result.webp new file mode 100644 index 0000000..1a6509f Binary files /dev/null and b/assets/media/sports-game-result.webp differ diff --git a/assets/media/sports-player-profile.webp b/assets/media/sports-player-profile.webp new file mode 100644 index 0000000..6f284c2 Binary files /dev/null and b/assets/media/sports-player-profile.webp differ diff --git a/assets/media/sports-signal-strip.webp b/assets/media/sports-signal-strip.webp new file mode 100644 index 0000000..4766354 Binary files /dev/null and b/assets/media/sports-signal-strip.webp differ diff --git a/assets/media/sports-tvgraphic-console.webp b/assets/media/sports-tvgraphic-console.webp new file mode 100644 index 0000000..1245a0d Binary files /dev/null and b/assets/media/sports-tvgraphic-console.webp differ diff --git a/assets/media/sports-wbdg-console.webp b/assets/media/sports-wbdg-console.webp new file mode 100644 index 0000000..fc948ec Binary files /dev/null and b/assets/media/sports-wbdg-console.webp differ diff --git a/assets/media/virtual-candidate-wall.webp b/assets/media/virtual-candidate-wall.webp new file mode 100644 index 0000000..792620f Binary files /dev/null and b/assets/media/virtual-candidate-wall.webp differ diff --git a/assets/media/virtual-debate-wall.webp b/assets/media/virtual-debate-wall.webp new file mode 100644 index 0000000..bdb9dda Binary files /dev/null and b/assets/media/virtual-debate-wall.webp differ diff --git a/assets/media/virtual-election-studio.webp b/assets/media/virtual-election-studio.webp new file mode 100644 index 0000000..01b4b73 Binary files /dev/null and b/assets/media/virtual-election-studio.webp differ diff --git a/assets/media/virtual-stage-data.webp b/assets/media/virtual-stage-data.webp new file mode 100644 index 0000000..c2991b5 Binary files /dev/null and b/assets/media/virtual-stage-data.webp differ diff --git a/assets/media/virtual-stage-floor.webp b/assets/media/virtual-stage-floor.webp new file mode 100644 index 0000000..3ff4b5d Binary files /dev/null and b/assets/media/virtual-stage-floor.webp differ diff --git a/assets/media/virtual-stage-wide.webp b/assets/media/virtual-stage-wide.webp new file mode 100644 index 0000000..470c765 Binary files /dev/null and b/assets/media/virtual-stage-wide.webp differ diff --git a/assets/media/world-map.webp b/assets/media/world-map.webp new file mode 100644 index 0000000..fd9f5c0 Binary files /dev/null and b/assets/media/world-map.webp differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..856a763 --- /dev/null +++ b/index.html @@ -0,0 +1,363 @@ + + + + + + + + 컴트로피 | Total IT Service + + + + + + + + + + + + + + + +
+
+ + +
+
+

Company Introduction

+

고객과 함께
성장하는
Total IT Service

+

+ 컴트로피는 실시간 방송 자막 송출 시스템, 방송 TV Graphic 솔루션, + 웹/앱 구축과 AI 솔루션을 개발하는 IT 솔루션 전문기업입니다. +

+ +
+ + +
+
+ +
+
+ Broadcast TV Graphic + Real-time Data + AI Learning Solution + Web Contents + Database System + Sports International Signal + Broadcast TV Graphic + Real-time Data + AI Learning Solution +
+
+ +
+
+
+

01 / About

+

고객 감동 실현을 기업의 사명으로 삼습니다.

+
+
+

+ 최고의 기술력과 서비스를 지향하며 고객 중심의 사업경쟁력을 강화합니다. + 핵심 서비스 분야의 품질을 보장하고, 고객의 가치 향상을 극대화할 수 + 있도록 끊임없이 개선합니다. +

+
+ Best People + Best Technical + Best Company +
+
+
+ +
+
+ Vision +

고객을 선도하는 창조적 리더상 수립

+

+ 새로운 IT 환경의 방향을 제시하고 IT 전문회사로 성장하는 미래가치, + 자기혁신의 가치, 창조적 도전의 가치를 실현합니다. +

+
+
+ Mission +

고객과 함께 성장하는 Total IT Service 전문기업

+

+ 고객을 가족처럼 대하고, 미래지향적인 기술 혁신과 신뢰경영을 바탕으로 + 고객과 가치를 공유하는 회사를 만듭니다. +

+
+
+
+ +
+
+
+ 디지털 네트워크 그래픽 +
+
+

Company Profile

+

방송사의 기술 연구소 역할을 대행하는 개발 파트너

+

+ 선거방송, 증권, 홈쇼핑, 스포츠와 게임 방송의 자막 송출 솔루션을 + 제공하고, 실시간 데이터 기반 방송 그래픽과 AI 솔루션, 웹 사이트 구축 + 사업역량을 강화하고 있습니다. +

+
+
+
사업 분야
+
소프트웨어 개발 및 공급, 방송 TV Graphic 솔루션, 웹 콘텐츠 개발
+
+
+
위치
+
서울특별시 금천구 서부샛길 606 대성지식산업센터 B동 1601호
+
+
+
+
+
+ +
+
+

02 / Clients

+

방송, 스포츠, 커머스, 게임 산업의 현장과 함께했습니다.

+
+
+
KPGA
+
KTV 국민방송
+
KT 알파 쇼핑
+
SK 스토아
+
WBDG
+
YTN
+
매일경제TV
+
연합뉴스TV
+
이데일리TV
+
Com2us
+
토마토증권통
+
신세계 쇼핑
+
MBC C&I
+
MBC
+
Riot Games
+
서울대학교병원
+
+
+ +
+
+

03 / Business

+

실시간 데이터를 화면 위의 정확한 언어로 바꿉니다.

+
+ +
+
+ 01 +

방송 그래픽 자막 송출 솔루션

+

선거방송, 홈쇼핑, 증권, 스포츠와 게임 데이터를 방송 그래픽으로 연결합니다.

+
+
+ 02 +

국제신호 제작

+

아시안게임, 동남아시안게임, 월드컵 등 국제경기 중계의 IS 제작 경험을 보유합니다.

+
+
+ 03 +

AI 솔루션 연구 개발

+

딥러닝 기반 영상 분석과 거리 측정 시스템 등 현장형 AI 솔루션을 개발합니다.

+
+
+ 04 +

데이터베이스 시스템 구축

+

실시간 데이터 연계, API, 데이터 송수신 프로그램과 방송 송출 서버를 설계합니다.

+
+
+ 05 +

웹 사이트 / 앱 개발

+

방송 운영 시스템과 연동되는 웹 페이지, 모바일 앱, 관리 도구를 구현합니다.

+
+
+ 06 +

버추얼 그래픽 시스템

+

Unreal Engine, Unity 기반 VR/AR 시스템과 실시간 3D 그래픽 처리를 제공합니다.

+
+
+
+ +
+
+
+

Project Fields

+

현장에서 검증된 여섯 가지 솔루션

+
+

+ 데이터 연동, 그래픽 송출, AI 분석, 운영 UI까지 현장 흐름에 맞춰 설계합니다. +

+
+ +
+
+ + + + + + +
+ +
+
+ 선거방송 후보자 득표 그래픽 화면 +
+
+
+

2.1 선거방송

+

선거방송 데이터 방송 그래픽 솔루션 개발

+

+ 선관위 데이터와 방송 그래픽을 실시간으로 연동해 자막 송출 시스템을 구성합니다. +

+
    +
    +
    +
    +
    + +
    +
    + 스포츠 TV 그래픽 운영 콘솔 +
    +
    +
    +

    Sports TV Graphic

    +

    데이터 인터페이스부터 사용자 중심 Output까지

    +
    +
    +
    Live Data자막시스템에서 사용 가능한 형태로 변환
    +
    HD/UHD고해상도 CG 제작과 송출 환경 대응
    +
    IS 제작국제경기 중계의 International Signal 제작
    +
    Design3D/2D Cut, 애니메이션, 특수 효과 적용
    +
    Custom UI운영자 중심 설계와 커스터마이징
    +
    All Sports구기, 투기, 계측 종목 등 다양한 종목 구성
    +
    +
    +
    + +
    +
    +
    +

    04 / Contact

    +

    방송 현장의 데이터를 안정적인 화면으로 연결합니다.

    +

    + 실시간 송출 시스템, 방송 그래픽, AI 영상 분석, 웹/앱 개발이 필요한 프로젝트를 + 컴트로피와 함께 구체화해보세요. +

    +
    +
    + 010-9008-2329 + ecoropy@naver.com +

    서울특별시 금천구 서부샛길 606 대성지식산업센터 B동 1601호

    +
    +
    +
    +
    + + + + + + + diff --git a/script.js b/script.js new file mode 100644 index 0000000..db8216b --- /dev/null +++ b/script.js @@ -0,0 +1,236 @@ +const caseData = { + election: { + kicker: "2.1 선거방송", + title: "선거방송 데이터 방송 그래픽 솔루션 개발", + description: "선관위 데이터와 방송 그래픽을 실시간으로 연동해 자막 송출 시스템을 구성합니다.", + bullets: [ + "선관위 데이터 실시간 연동 코드 적용", + "데이터 스케줄러와 송출 컨트롤러 시스템 개발", + "방송 그래픽과 데이터 연동을 통한 실시간 자막 송출" + ], + images: [ + { src: "assets/media/election-candidate-screen.webp", alt: "선거방송 후보자 득표 그래픽 화면" }, + { src: "assets/media/election-seat-map.webp", alt: "선거방송 의석 현황 그래픽 화면" }, + { src: "assets/media/election-region-map.webp", alt: "선거방송 전국 판세 지도 그래픽" } + ] + }, + virtual: { + kicker: "2.2 버추얼 그래픽 시스템", + title: "버추얼 그래픽 솔루션 개발", + description: "Unreal Engine과 Unity를 활용해 VR, AR 기반의 실시간 3D 그래픽 시스템을 개발합니다.", + bullets: [ + "Unreal Engine 기반 VR/AR 시스템 개발", + "실시간 데이터 3D 그래픽 처리 시스템 적용", + "Unity 활용 영상 콘텐츠 제작" + ], + images: [ + { src: "assets/media/virtual-election-studio.webp", alt: "버추얼 선거방송 스튜디오 그래픽" }, + { src: "assets/media/virtual-candidate-wall.webp", alt: "버추얼 후보자 데이터 월" }, + { src: "assets/media/virtual-debate-wall.webp", alt: "버추얼 토론 방송 그래픽 월" } + ] + }, + finance: { + kicker: "2.3 데이터베이스 / 경제 방송", + title: "증권 데이터 및 경제 방송 송출 그래픽 시스템", + description: "코스콤 데이터와 해외 지수 데이터를 연계해 방송 송출 그래픽과 API 서버를 구현합니다.", + bullets: [ + "코스콤 데이터와 해외 지수 연계 데이터베이스 서버 구축", + "실시간 그래픽 연계 데이터 송수신 프로그램 개발", + "REST 서버 API 구현 및 방송 송출 시스템 적용" + ], + images: [ + { src: "assets/media/finance-chart.webp", alt: "경제 방송 주가 차트 그래픽" }, + { src: "assets/media/finance-index.webp", alt: "경제 방송 지수 그래픽" }, + { src: "assets/media/finance-db-console.webp", alt: "경제 방송 데이터베이스 콘솔" } + ] + }, + ai: { + kicker: "2.4 AI 학습 솔루션", + title: "AI 기반 거리 측정 시스템", + description: "KPGA 공식 기록에 사용되는 그린 홀 컵 간 거리 측정 솔루션을 개발했습니다.", + bullets: [ + "CUDA 기반 딥러닝 모델 학습", + "카메라 영상 신호 수신 후 공 위치와 좌표 변환", + "골프 중계와 기록 환경에 맞춘 AI 거리 측정" + ], + images: [ + { src: "assets/media/ai-distance-result.webp", alt: "AI 기반 거리 측정 결과 화면" }, + { src: "assets/media/ai-training-green.webp", alt: "골프 그린 AI 학습 화면" }, + { src: "assets/media/ai-detection-console.webp", alt: "AI 영상 분석 콘솔 화면" } + ] + }, + shopping: { + kicker: "2.5 홈쇼핑 송출 시스템", + title: "홈쇼핑 자동화 송출 시스템 / 라이브 톡", + description: "송출 스케줄과 원격 제어, 모바일 연동을 포함한 홈쇼핑 방송 운영 시스템을 개발합니다.", + bullets: [ + "송출 스케줄 관리 데이터 송수신 모듈 개발", + "홈쇼핑 송출 프로그램 원격제어 로컬/모바일 연동", + "웹 페이지와 앱을 활용한 실시간 방송 데이터 송출" + ], + images: [ + { src: "assets/media/shopping-control-dashboard.webp", alt: "홈쇼핑 송출 제어 대시보드" }, + { src: "assets/media/shopping-live-output.webp", alt: "홈쇼핑 라이브 방송 송출 화면" }, + { src: "assets/media/mobile-live-talk.webp", alt: "홈쇼핑 모바일 라이브 톡 화면" } + ] + }, + sports: { + kicker: "2.6 스포츠 TV Graphic", + title: "스포츠 / 게임 데이터 솔루션 송출 시스템 개발", + description: "Live Data를 자막시스템에서 사용 가능한 형태로 변환하고 다양한 종목의 TVG 시스템을 제작합니다.", + bullets: [ + "HD/UHD급 CG 제작과 국제신호 제작", + "3D/2D Cut, 애니메이션 등 특수 효과 적용", + "구기, 투기, 계측 종목 등 다양한 스포츠 TVG 구성" + ], + images: [ + { src: "assets/media/sports-game-result.webp", alt: "게임 결과 방송 그래픽" }, + { src: "assets/media/sports-player-profile.webp", alt: "선수 프로필 방송 그래픽" }, + { src: "assets/media/football-scorebug.webp", alt: "축구 스코어버그 방송 그래픽" } + ] + } +}; + +const body = document.body; +const header = document.getElementById("siteHeader"); +const mobilePanel = document.getElementById("mobilePanel"); +const menuToggle = document.querySelector(".menu-toggle"); +const cursor = document.querySelector(".cursor"); +const loaderBar = document.getElementById("loaderBar"); +const loaderValue = document.getElementById("loaderValue"); +const caseImage = document.getElementById("caseImage"); +const caseKicker = document.getElementById("caseKicker"); +const caseName = document.getElementById("caseName"); +const caseDescription = document.getElementById("caseDescription"); +const caseBullets = document.getElementById("caseBullets"); +const caseThumbs = document.getElementById("caseThumbs"); +const navLinks = [...document.querySelectorAll(".primary-nav a")]; + +let loaderProgress = 0; +const loaderTimer = window.setInterval(() => { + loaderProgress = Math.min(loaderProgress + Math.ceil(Math.random() * 12), 100); + loaderBar.style.width = `${loaderProgress}%`; + loaderValue.textContent = String(loaderProgress).padStart(2, "0"); + if (loaderProgress >= 100) { + window.clearInterval(loaderTimer); + window.setTimeout(() => { + body.classList.remove("is-loading"); + body.classList.add("is-ready"); + }, 220); + } +}, 55); + +const updateScrollState = () => { + const scrollTop = window.scrollY || document.documentElement.scrollTop; + const scrollable = document.documentElement.scrollHeight - window.innerHeight; + const progress = scrollable > 0 ? (scrollTop / scrollable) * 100 : 0; + header.classList.toggle("is-scrolled", scrollTop > 20); + header.style.setProperty("--page-progress", `${progress}%`); + + let currentHref = navLinks[0]?.getAttribute("href"); + navLinks.forEach(link => { + const target = document.querySelector(link.getAttribute("href")); + if (target && target.getBoundingClientRect().top <= window.innerHeight * 0.45) { + currentHref = link.getAttribute("href"); + } + }); + navLinks.forEach(link => { + link.setAttribute("aria-current", link.getAttribute("href") === currentHref ? "true" : "false"); + }); +}; + +window.addEventListener("scroll", updateScrollState, { passive: true }); +window.addEventListener("resize", updateScrollState); +updateScrollState(); + +const revealObserver = new IntersectionObserver( + entries => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.classList.add("in-view"); + revealObserver.unobserve(entry.target); + } + }); + }, + { threshold: 0.16 } +); + +document.querySelectorAll(".reveal").forEach(element => revealObserver.observe(element)); + +const setMenuOpen = open => { + menuToggle.setAttribute("aria-expanded", String(open)); + menuToggle.setAttribute("aria-label", open ? "메뉴 닫기" : "메뉴 열기"); + mobilePanel.classList.toggle("is-open", open); + mobilePanel.setAttribute("aria-hidden", String(!open)); + menuToggle.innerHTML = ``; + if (window.lucide) window.lucide.createIcons(); +}; + +if (menuToggle) { + menuToggle.addEventListener("click", () => { + const open = menuToggle.getAttribute("aria-expanded") !== "true"; + setMenuOpen(open); + }); +} + +mobilePanel.querySelectorAll("a").forEach(link => { + link.addEventListener("click", () => setMenuOpen(false)); +}); + +const renderCase = (key, imageIndex = 0) => { + const data = caseData[key]; + const image = data.images[imageIndex]; + caseImage.src = image.src; + caseImage.alt = image.alt; + caseKicker.textContent = data.kicker; + caseName.textContent = data.title; + caseDescription.textContent = data.description; + caseBullets.innerHTML = data.bullets.map(item => `
  • ${item}
  • `).join(""); + caseThumbs.innerHTML = data.images + .map( + (item, index) => ` + + ` + ) + .join(""); + + caseThumbs.querySelectorAll("button").forEach(button => { + button.addEventListener("click", () => renderCase(key, Number(button.dataset.caseThumb))); + }); +}; + +document.querySelectorAll(".case-tabs button").forEach(button => { + button.addEventListener("click", () => { + document.querySelectorAll(".case-tabs button").forEach(item => { + item.classList.remove("is-active"); + item.setAttribute("aria-selected", "false"); + }); + button.classList.add("is-active"); + button.setAttribute("aria-selected", "true"); + renderCase(button.dataset.case); + }); +}); + +renderCase("election"); + +if (window.matchMedia("(pointer: fine)").matches && cursor) { + window.addEventListener("pointermove", event => { + cursor.style.transform = `translate3d(${event.clientX}px, ${event.clientY}px, 0) translate(-50%, -50%)`; + cursor.classList.add("is-visible"); + }); + + document.querySelectorAll("a, button").forEach(element => { + element.addEventListener("pointerenter", () => cursor.classList.add("is-active")); + element.addEventListener("pointerleave", () => cursor.classList.remove("is-active")); + }); +} + +window.addEventListener("keydown", event => { + if (event.key === "Escape") setMenuOpen(false); +}); + +if (window.lucide) { + window.lucide.createIcons(); +} diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..bc3577a --- /dev/null +++ b/styles.css @@ -0,0 +1,1467 @@ +:root { + --ink: #070706; + --ink-2: #11110f; + --ink-3: #1b1b17; + --paper: #f1eee6; + --paper-2: #d8d3c8; + --muted: #a7a197; + --muted-dark: #766f64; + --line: rgba(241, 238, 230, 0.15); + --line-strong: rgba(241, 238, 230, 0.32); + --hot: #f04f2f; + --hot-2: #ff724c; + --signal: #c8ff49; + --cyan: #73ddff; + --steel: #a8bdc2; + --display: "Barlow Condensed", "Noto Sans KR", sans-serif; + --body: "Noto Sans KR", system-ui, sans-serif; + --mono: "IBM Plex Mono", "Noto Sans KR", monospace; + --shell: min(91vw, 1480px); + --header-h: 82px; + --ease: cubic-bezier(0.2, 0.78, 0.2, 1); + --ease-out: cubic-bezier(0.16, 1, 0.3, 1); +} + +* { + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; + scroll-padding-top: 94px; + background: var(--ink); +} + +body { + margin: 0; + background: + linear-gradient(90deg, rgba(255, 255, 255, 0.035) 1px, transparent 1px) 0 0 / 84px 84px, + linear-gradient(180deg, rgba(255, 255, 255, 0.025) 1px, transparent 1px) 0 0 / 84px 84px, + var(--ink); + color: var(--paper); + font-family: var(--body); + font-size: 16px; + line-height: 1.7; + letter-spacing: 0; + overflow-x: clip; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; +} + +body.is-loading { + overflow: hidden; +} + +html.no-js body.is-loading { + overflow: auto; +} + +body::before { + content: ""; + position: fixed; + inset: 0; + z-index: 9000; + pointer-events: none; + opacity: 0.035; + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E"); + mix-blend-mode: soft-light; +} + +img { + display: block; + max-width: 100%; +} + +a { + color: inherit; + text-decoration: none; +} + +button, +input, +textarea, +select { + font: inherit; +} + +button { + color: inherit; +} + +button, +a { + -webkit-tap-highlight-color: transparent; +} + +::selection { + background: var(--hot); + color: #fff; +} + +:focus-visible { + outline: 2px solid var(--signal); + outline-offset: 4px; +} + +.shell { + width: var(--shell); + margin-inline: auto; +} + +.section { + position: relative; +} + +.eyebrow { + display: flex; + align-items: center; + gap: 12px; + margin: 0 0 20px; + color: var(--muted); + font-family: var(--mono); + font-size: 0.78rem; + font-weight: 600; + letter-spacing: 0; + text-transform: uppercase; +} + +.eyebrow::before { + content: ""; + width: 34px; + height: 1px; + background: currentColor; +} + +.button { + position: relative; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 10px; + min-height: 52px; + padding: 0 20px; + border: 1px solid var(--line-strong); + border-radius: 4px; + background: rgba(7, 7, 6, 0.36); + color: var(--paper); + font-family: var(--mono); + font-size: 0.75rem; + font-weight: 600; + letter-spacing: 0; + text-transform: uppercase; + overflow: hidden; + isolation: isolate; + transition: color 0.35s var(--ease), border-color 0.35s var(--ease), transform 0.35s var(--ease); +} + +.button::before { + content: ""; + position: absolute; + inset: 0; + z-index: -1; + background: var(--paper); + transform: translateY(104%); + transition: transform 0.42s var(--ease-out); +} + +.button svg { + width: 18px; + height: 18px; + stroke-width: 2; + transition: transform 0.35s var(--ease); +} + +.button:hover, +.button:focus-visible { + color: var(--ink); + border-color: var(--paper); + transform: translateY(-2px); +} + +.button:hover::before, +.button:focus-visible::before { + transform: translateY(0); +} + +.button:hover svg, +.button:focus-visible svg { + transform: translate(3px, -3px); +} + +.button--hot { + border-color: var(--hot); + background: var(--hot); + color: #fff; +} + +.button--hot::before { + background: var(--hot-2); +} + +.button--hot:hover, +.button--hot:focus-visible { + color: #fff; + border-color: var(--hot-2); +} + +.loader { + position: fixed; + inset: 0; + z-index: 10000; + display: grid; + place-items: center; + background: var(--ink); + transition: opacity 0.72s var(--ease), visibility 0.72s; +} + +html.no-js .loader { + display: none; +} + +.loader__inner { + width: min(620px, 84vw); +} + +.loader__top, +.loader__foot { + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: 24px; +} + +.loader__top strong { + font-family: var(--display); + font-size: 3rem; + line-height: 0.9; +} + +.loader__top span, +.loader__foot { + color: var(--muted); + font-family: var(--mono); + font-size: 0.74rem; + text-transform: uppercase; +} + +.loader__track { + position: relative; + height: 1px; + margin: 18px 0 14px; + background: var(--line); +} + +.loader__track span { + position: absolute; + inset: 0 auto 0 0; + width: 0; + background: var(--hot-2); + box-shadow: 0 0 20px rgba(255, 114, 76, 0.5); +} + +body.is-ready .loader { + visibility: hidden; + opacity: 0; + pointer-events: none; +} + +.cursor { + position: fixed; + left: 0; + top: 0; + z-index: 9999; + width: 32px; + height: 32px; + border: 1px solid rgba(241, 238, 230, 0.62); + border-radius: 50%; + pointer-events: none; + opacity: 0; + transform: translate3d(-50%, -50%, 0); + mix-blend-mode: difference; + transition: width 0.22s var(--ease), height 0.22s var(--ease), opacity 0.22s, background 0.22s var(--ease); +} + +.cursor::after { + content: ""; + position: absolute; + left: 50%; + top: 50%; + width: 3px; + height: 3px; + border-radius: 50%; + background: #fff; + transform: translate(-50%, -50%); +} + +.cursor.is-visible { + opacity: 1; +} + +.cursor.is-active { + width: 52px; + height: 52px; + background: rgba(255, 255, 255, 0.11); +} + +.site-header { + position: fixed; + inset: 0 0 auto; + z-index: 1000; + height: var(--header-h); + display: flex; + align-items: center; + transition: height 0.35s var(--ease), background 0.35s var(--ease), border-color 0.35s var(--ease), backdrop-filter 0.35s var(--ease); +} + +.site-header.is-scrolled { + height: 68px; + border-bottom: 1px solid var(--line); + background: rgba(7, 7, 6, 0.74); + backdrop-filter: blur(18px) saturate(130%); +} + +.header__inner { + position: relative; + z-index: 2; + width: var(--shell); + margin-inline: auto; + display: grid; + grid-template-columns: 1fr auto 1fr; + align-items: center; + gap: 24px; +} + +.brand { + display: inline-flex; + width: max-content; + align-items: center; + gap: 11px; + font-family: var(--display); + font-size: 1.55rem; + font-weight: 900; + line-height: 0.9; + letter-spacing: 0; +} + +.brand__mark { + display: grid; + width: 29px; + height: 29px; + place-items: center; + background: var(--hot); + color: #fff; + font-size: 1rem; + transition: transform 0.45s var(--ease-out); +} + +.brand:hover .brand__mark, +.brand:focus-visible .brand__mark { + transform: rotate(90deg); +} + +.primary-nav { + display: flex; + align-items: center; + justify-content: center; + gap: 34px; +} + +.primary-nav a { + position: relative; + padding: 14px 0; + color: rgba(241, 238, 230, 0.72); + font-family: var(--mono); + font-size: 0.76rem; + font-weight: 600; + letter-spacing: 0; + transition: color 0.28s var(--ease); +} + +.primary-nav a::after { + content: ""; + position: absolute; + left: 0; + right: 0; + bottom: 8px; + height: 1px; + background: var(--hot-2); + transform: scaleX(0); + transform-origin: right; + transition: transform 0.34s var(--ease); +} + +.primary-nav a:hover, +.primary-nav a:focus-visible, +.primary-nav a[aria-current="true"] { + color: var(--paper); +} + +.primary-nav a:hover::after, +.primary-nav a:focus-visible::after, +.primary-nav a[aria-current="true"]::after { + transform: scaleX(1); + transform-origin: left; +} + +.header__contact { + justify-self: end; + display: inline-flex; + align-items: center; + gap: 9px; + min-height: 42px; + padding: 0 14px; + border: 1px solid var(--line); + border-radius: 4px; + color: var(--paper); + font-family: var(--mono); + font-size: 0.72rem; + font-weight: 600; + letter-spacing: 0; + transition: background 0.3s var(--ease), border-color 0.3s var(--ease); +} + +.header__contact svg, +.menu-toggle svg { + width: 17px; + height: 17px; +} + +.header__contact:hover, +.header__contact:focus-visible { + border-color: var(--hot-2); + background: rgba(240, 79, 47, 0.16); +} + +.menu-toggle { + display: none; + justify-self: end; + width: 44px; + height: 44px; + place-items: center; + border: 1px solid var(--line); + border-radius: 4px; + background: rgba(7, 7, 6, 0.28); + cursor: pointer; +} + +.scroll-progress { + position: absolute; + left: 0; + bottom: 0; + width: var(--page-progress, 0%); + height: 1px; + background: var(--hot-2); + box-shadow: 0 0 14px rgba(255, 114, 76, 0.46); +} + +.mobile-panel { + position: fixed; + inset: 0; + z-index: 900; + display: grid; + align-content: space-between; + padding: 120px 5vw 32px; + background: var(--ink); + transform: translateY(-102%); + transition: transform 0.55s var(--ease-out); +} + +.mobile-panel.is-open { + transform: translateY(0); +} + +.mobile-panel nav { + display: grid; +} + +.mobile-panel a { + display: grid; + grid-template-columns: 48px 1fr; + align-items: center; + padding: 18px 0; + border-bottom: 1px solid var(--line); + font-family: var(--display); + font-size: 3.2rem; + font-weight: 800; + line-height: 0.95; +} + +.mobile-panel a span { + color: var(--muted); + font-family: var(--mono); + font-size: 0.72rem; +} + +.mobile-panel p { + max-width: 340px; + margin: 0; + color: var(--muted); + font-size: 0.9rem; +} + +.hero { + min-height: 86svh; + display: grid; + align-items: end; + padding: calc(var(--header-h) + 76px) 0 54px; + overflow: hidden; +} + +.hero__media { + position: absolute; + inset: 0; + z-index: -3; +} + +.hero__media img { + width: 100%; + height: 100%; + object-fit: cover; + object-position: 68% 50%; + opacity: 1; + filter: brightness(1.28) saturate(1.08); +} + +.hero__shade { + position: absolute; + inset: 0; + z-index: -2; + background: + linear-gradient(90deg, rgba(7, 7, 6, 0.93), rgba(7, 7, 6, 0.56) 46%, rgba(7, 7, 6, 0.12) 100%), + linear-gradient(180deg, rgba(7, 7, 6, 0.06), var(--ink) 96%); +} + +.hero__inner { + display: grid; + grid-template-columns: minmax(0, 1.05fr) minmax(360px, 0.72fr); + align-items: end; + gap: 54px; +} + +.hero__copy { + max-width: 790px; +} + +.hero h1 { + margin: 0; + max-width: 820px; + font-family: var(--display); + font-size: 6.7rem; + font-weight: 900; + line-height: 0.88; + letter-spacing: 0; + text-transform: uppercase; +} + +.hero__lead { + max-width: 650px; + margin: 28px 0 0; + color: var(--paper-2); + font-size: 1.12rem; + word-break: keep-all; +} + +.hero__actions { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 34px; +} + +.hero__console { + border: 1px solid var(--line-strong); + border-radius: 6px; + background: rgba(7, 7, 6, 0.58); + box-shadow: 0 24px 70px rgba(0, 0, 0, 0.35); + backdrop-filter: blur(16px) saturate(120%); + overflow: hidden; +} + +.console__top { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 18px; + border-bottom: 1px solid var(--line); + font-family: var(--mono); + font-size: 0.72rem; + color: var(--muted); +} + +.console__top strong { + color: var(--signal); +} + +.signal-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 1px; + background: var(--line); +} + +.signal-grid span { + min-height: 58px; + display: flex; + align-items: center; + padding: 14px 16px; + background: rgba(7, 7, 6, 0.74); + color: var(--paper-2); + font-size: 0.87rem; + font-weight: 700; +} + +.hero__console img { + width: 100%; + height: 230px; + object-fit: cover; + object-position: center; + border-top: 1px solid var(--line); +} + +.ticker { + overflow: hidden; + border-top: 1px solid var(--line); + border-bottom: 1px solid var(--line); + background: var(--hot); + color: #fff; +} + +.ticker__track { + display: flex; + width: max-content; + animation: tickerMove 32s linear infinite; +} + +.ticker span { + padding: 14px 34px; + font-family: var(--mono); + font-size: 0.78rem; + font-weight: 600; + letter-spacing: 0; + white-space: nowrap; + text-transform: uppercase; +} + +@keyframes tickerMove { + from { + transform: translateX(0); + } + to { + transform: translateX(-50%); + } +} + +.about { + padding: 122px 0 96px; +} + +.about__grid { + display: grid; + grid-template-columns: 0.92fr 1fr; + gap: 80px; + align-items: start; +} + +.section-heading h2, +.intro-band h2, +.case-lab h2, +.sports-system h2, +.contact h2 { + margin: 0; + font-family: var(--display); + font-size: 4.6rem; + font-weight: 900; + line-height: 0.96; + letter-spacing: 0; + text-transform: uppercase; + word-break: keep-all; +} + +.section-heading--wide { + max-width: 920px; +} + +.about__body p, +.intro-band__copy p, +.case-lab__head > p, +.contact__copy p { + margin: 0; + color: var(--paper-2); + font-size: 1.06rem; + word-break: keep-all; +} + +.value-strip { + display: grid; + grid-template-columns: repeat(3, 1fr); + margin-top: 34px; + border: 1px solid var(--line); +} + +.value-strip strong { + min-height: 98px; + display: grid; + place-items: center; + padding: 18px; + border-right: 1px solid var(--line); + color: var(--signal); + font-family: var(--display); + font-size: 1.7rem; + line-height: 0.96; + text-align: center; +} + +.value-strip strong:last-child { + border-right: 0; +} + +.mission-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 18px; + margin-top: 72px; +} + +.mission-panel { + min-height: 300px; + padding: 32px; + border: 1px solid var(--line); + border-radius: 6px; + background: rgba(255, 255, 255, 0.035); +} + +.mission-panel span { + color: var(--hot-2); + font-family: var(--mono); + font-size: 0.78rem; + font-weight: 600; +} + +.mission-panel h3 { + max-width: 520px; + margin: 54px 0 18px; + font-size: 1.65rem; + line-height: 1.24; + word-break: keep-all; +} + +.mission-panel p { + margin: 0; + color: var(--muted); + word-break: keep-all; +} + +.mission-panel--accent { + background: var(--paper); + color: var(--ink); +} + +.mission-panel--accent p { + color: #4a453d; +} + +.intro-band { + padding: 96px 0; + background: var(--paper); + color: var(--ink); + overflow: hidden; +} + +.intro-band__grid { + display: grid; + grid-template-columns: 0.78fr 1fr; + gap: 70px; + align-items: center; +} + +.intro-band__image { + position: relative; + min-height: 420px; + display: grid; + place-items: center; + border: 1px solid rgba(7, 7, 6, 0.18); + border-radius: 6px; + background: + linear-gradient(90deg, rgba(7, 7, 6, 0.07) 1px, transparent 1px) 0 0 / 48px 48px, + linear-gradient(180deg, rgba(7, 7, 6, 0.07) 1px, transparent 1px) 0 0 / 48px 48px, + #e8e3d8; +} + +.intro-band__image img { + width: min(78%, 430px); +} + +.intro-band .eyebrow, +.intro-band__copy p { + color: #585247; +} + +.profile-list { + display: grid; + gap: 1px; + margin: 34px 0 0; + background: rgba(7, 7, 6, 0.16); +} + +.profile-list div { + display: grid; + grid-template-columns: 150px 1fr; + gap: 24px; + padding: 18px 0; + background: var(--paper); +} + +.profile-list dt { + color: var(--hot); + font-weight: 900; +} + +.profile-list dd { + margin: 0; + color: #302d28; +} + +.clients { + padding: 116px 0 104px; +} + +.logo-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 1px; + margin-top: 44px; + background: var(--line); + border: 1px solid var(--line); +} + +.logo-grid figure { + min-height: 116px; + display: grid; + place-items: center; + margin: 0; + padding: 22px; + background: var(--paper); +} + +.logo-grid img { + max-width: 82%; + max-height: 58px; + object-fit: contain; +} + +.services { + padding: 116px 0; + background: var(--ink-2); +} + +.service-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1px; + margin-top: 52px; + background: var(--line); + border: 1px solid var(--line); +} + +.service-card { + min-height: 300px; + padding: 28px; + background: var(--ink-2); + transition: background 0.35s var(--ease), transform 0.35s var(--ease); +} + +.service-card:hover { + background: var(--ink-3); + transform: translateY(-4px); +} + +.service-card span { + color: var(--hot-2); + font-family: var(--mono); + font-size: 0.78rem; + font-weight: 600; +} + +.service-card h3 { + margin: 82px 0 16px; + font-size: 1.45rem; + line-height: 1.28; + word-break: keep-all; +} + +.service-card p { + margin: 0; + color: var(--muted); + word-break: keep-all; +} + +.case-lab { + padding: 122px 0; +} + +.case-lab__head { + display: grid; + grid-template-columns: 1fr minmax(260px, 420px); + gap: 42px; + align-items: end; +} + +.case-lab__grid { + display: grid; + grid-template-columns: 310px 1fr; + gap: 28px; + margin-top: 52px; +} + +.case-tabs { + display: grid; + align-self: start; + border: 1px solid var(--line); + border-radius: 6px; + overflow: hidden; +} + +.case-tabs button { + display: grid; + grid-template-columns: 26px 1fr; + align-items: center; + gap: 12px; + min-height: 64px; + padding: 0 18px; + border: 0; + border-bottom: 1px solid var(--line); + background: rgba(255, 255, 255, 0.03); + color: var(--muted); + cursor: pointer; + text-align: left; + font-weight: 800; + letter-spacing: 0; + transition: background 0.28s var(--ease), color 0.28s var(--ease), padding-left 0.28s var(--ease); +} + +.case-tabs button:last-child { + border-bottom: 0; +} + +.case-tabs svg { + width: 19px; + height: 19px; + stroke-width: 2; +} + +.case-tabs button:hover, +.case-tabs button:focus-visible, +.case-tabs button.is-active { + padding-left: 24px; + background: var(--paper); + color: var(--ink); +} + +.case-stage { + display: grid; + grid-template-columns: minmax(0, 1.08fr) minmax(330px, 0.62fr); + min-height: 640px; + border: 1px solid var(--line); + border-radius: 6px; + background: rgba(255, 255, 255, 0.035); + overflow: hidden; +} + +.case-stage__media { + position: relative; + min-height: 420px; + display: grid; + background: #050505; +} + +.case-stage__media > img { + width: 100%; + height: 100%; + object-fit: contain; + object-position: center; +} + +.case-stage__thumbs { + position: absolute; + left: 18px; + right: 18px; + bottom: 18px; + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 10px; +} + +.case-stage__thumbs button { + padding: 0; + border: 1px solid rgba(241, 238, 230, 0.34); + border-radius: 4px; + background: #050505; + cursor: pointer; + overflow: hidden; + opacity: 0.72; + transition: opacity 0.24s var(--ease), border-color 0.24s var(--ease), transform 0.24s var(--ease); +} + +.case-stage__thumbs button.is-active, +.case-stage__thumbs button:hover, +.case-stage__thumbs button:focus-visible { + opacity: 1; + border-color: var(--signal); + transform: translateY(-2px); +} + +.case-stage__thumbs img { + width: 100%; + aspect-ratio: 16 / 9; + object-fit: cover; +} + +.case-stage__copy { + display: flex; + flex-direction: column; + justify-content: end; + padding: 38px; +} + +.case-stage__kicker { + margin: 0 0 18px; + color: var(--hot-2); + font-family: var(--mono); + font-size: 0.78rem; + font-weight: 600; +} + +.case-stage h3 { + margin: 0; + font-size: 2rem; + line-height: 1.22; + word-break: keep-all; +} + +.case-stage__copy > p:not(.case-stage__kicker) { + margin: 18px 0 0; + color: var(--paper-2); + word-break: keep-all; +} + +.case-stage ul { + display: grid; + gap: 12px; + margin: 28px 0 0; + padding: 0; + list-style: none; +} + +.case-stage li { + position: relative; + padding-left: 18px; + color: var(--muted); + word-break: keep-all; +} + +.case-stage li::before { + content: ""; + position: absolute; + left: 0; + top: 0.72em; + width: 6px; + height: 6px; + background: var(--signal); +} + +.sports-system { + min-height: 760px; + display: grid; + align-items: end; + padding: 120px 0 90px; + overflow: hidden; +} + +.sports-system__image { + position: absolute; + inset: 0; + z-index: -2; +} + +.sports-system__image img { + width: 100%; + height: 100%; + object-fit: cover; + opacity: 0.48; +} + +.sports-system::after { + content: ""; + position: absolute; + inset: 0; + z-index: -1; + background: + linear-gradient(90deg, var(--ink) 0%, rgba(7, 7, 6, 0.86) 42%, rgba(7, 7, 6, 0.3) 100%), + linear-gradient(180deg, rgba(7, 7, 6, 0.1), var(--ink) 100%); +} + +.sports-system__content { + display: grid; + grid-template-columns: 0.9fr 1fr; + gap: 62px; + align-items: end; +} + +.system-list { + display: grid; + grid-template-columns: repeat(2, 1fr); + border: 1px solid var(--line); + background: rgba(7, 7, 6, 0.54); + backdrop-filter: blur(10px); +} + +.system-list div { + min-height: 130px; + display: flex; + flex-direction: column; + justify-content: space-between; + gap: 18px; + padding: 20px; + border-right: 1px solid var(--line); + border-bottom: 1px solid var(--line); +} + +.system-list div:nth-child(2n) { + border-right: 0; +} + +.system-list div:nth-last-child(-n + 2) { + border-bottom: 0; +} + +.system-list strong { + color: var(--cyan); + font-family: var(--display); + font-size: 1.65rem; + line-height: 0.95; +} + +.system-list span { + color: var(--paper-2); + font-size: 0.92rem; + word-break: keep-all; +} + +.contact { + padding: 112px 0; + background: var(--paper); + color: var(--ink); +} + +.contact__grid { + display: grid; + grid-template-columns: 1fr minmax(340px, 520px); + gap: 70px; + align-items: end; +} + +.contact .eyebrow, +.contact__copy p { + color: #5d574d; +} + +.contact-card { + display: grid; + gap: 1px; + margin: 0; + border: 1px solid rgba(7, 7, 6, 0.14); + border-radius: 6px; + background: rgba(7, 7, 6, 0.14); + overflow: hidden; + font-style: normal; +} + +.contact-card a, +.contact-card p { + display: grid; + grid-template-columns: 28px 1fr; + align-items: center; + gap: 14px; + min-height: 72px; + margin: 0; + padding: 18px 20px; + background: var(--paper); + color: #211f1b; + word-break: keep-all; +} + +.contact-card svg { + width: 20px; + height: 20px; + color: var(--hot); +} + +.site-footer { + padding: 28px 0; + border-top: 1px solid var(--line); + background: var(--ink); +} + +.site-footer .shell { + display: flex; + align-items: center; + justify-content: space-between; + gap: 24px; + color: var(--muted); + font-family: var(--mono); + font-size: 0.78rem; +} + +.site-footer strong { + color: var(--paper); + font-family: var(--display); + font-size: 1.6rem; +} + +html.js .reveal { + opacity: 0; + transform: translateY(34px); + transition: opacity 0.86s var(--ease-out), transform 0.86s var(--ease-out); +} + +html.js .reveal.in-view { + opacity: 1; + transform: none; +} + +html.js .reveal[data-delay="1"] { + transition-delay: 0.08s; +} + +html.js .reveal[data-delay="2"] { + transition-delay: 0.16s; +} + +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.001ms !important; + animation-iteration-count: 1 !important; + scroll-behavior: auto !important; + transition-duration: 0.001ms !important; + } + + .cursor { + display: none; + } +} + +@media (max-width: 1180px) { + .hero h1 { + font-size: 5.2rem; + } + + .hero__inner, + .about__grid, + .intro-band__grid, + .sports-system__content, + .contact__grid { + grid-template-columns: 1fr; + } + + .hero__console { + max-width: 560px; + } + + .service-grid, + .logo-grid { + grid-template-columns: repeat(2, 1fr); + } + + .case-lab__grid, + .case-stage { + grid-template-columns: 1fr; + } + + .case-tabs { + grid-template-columns: repeat(3, 1fr); + } + + .case-tabs button:nth-child(3) { + border-right: 0; + } + + .case-tabs button { + border-right: 1px solid var(--line); + } +} + +@media (max-width: 820px) { + :root { + --header-h: 70px; + } + + body { + font-size: 15px; + } + + .primary-nav, + .header__contact { + display: none; + } + + .header__inner { + grid-template-columns: 1fr auto; + } + + .menu-toggle { + display: grid; + } + + .brand { + font-size: 1.35rem; + } + + .hero { + min-height: 88svh; + padding: calc(var(--header-h) + 54px) 0 40px; + } + + .hero__shade { + background: + linear-gradient(180deg, rgba(7, 7, 6, 0.72), rgba(7, 7, 6, 0.8) 48%, var(--ink) 100%), + linear-gradient(90deg, rgba(7, 7, 6, 0.8), rgba(7, 7, 6, 0.24)); + } + + .hero__inner { + gap: 34px; + } + + .hero h1, + .section-heading h2, + .intro-band h2, + .case-lab h2, + .sports-system h2, + .contact h2 { + font-size: 3.15rem; + } + + .hero__lead { + font-size: 1rem; + } + + .hero__actions { + align-items: stretch; + } + + .button { + width: 100%; + } + + .signal-grid, + .mission-grid, + .value-strip, + .system-list, + .service-grid, + .logo-grid { + grid-template-columns: 1fr; + } + + .value-strip strong, + .system-list div, + .system-list div:nth-child(2n), + .system-list div:nth-last-child(-n + 2) { + border-right: 0; + border-bottom: 1px solid var(--line); + } + + .value-strip strong:last-child, + .system-list div:last-child { + border-bottom: 0; + } + + .about, + .clients, + .services, + .case-lab, + .contact { + padding: 82px 0; + } + + .intro-band { + padding: 76px 0; + } + + .intro-band__image { + min-height: 300px; + } + + .profile-list div { + grid-template-columns: 1fr; + gap: 6px; + } + + .case-lab__head { + grid-template-columns: 1fr; + } + + .case-tabs { + grid-template-columns: 1fr; + } + + .case-tabs button { + border-right: 0; + } + + .case-stage { + min-height: 0; + } + + .case-stage__copy { + padding: 28px; + } + + .case-stage h3 { + font-size: 1.55rem; + } + + .case-stage__thumbs { + position: static; + padding: 12px; + background: var(--ink); + } + + .sports-system { + min-height: 0; + padding: 82px 0; + } + + .site-footer .shell { + align-items: flex-start; + flex-direction: column; + } +} + +@media (max-width: 520px) { + .hero h1, + .section-heading h2, + .intro-band h2, + .case-lab h2, + .sports-system h2, + .contact h2 { + font-size: 2.58rem; + } + + .hero__console { + display: none; + } + + .mission-panel, + .service-card { + padding: 24px; + } + + .logo-grid figure { + min-height: 104px; + } + + .mobile-panel a { + font-size: 2.48rem; + } +}