
    i{>                     H   d Z ddlZddlZddlZddlmZ ddlZddlmZ ddl	m
Z
mZmZ e
dz  Zedz  Zedz  Zed	z  Zej#                  d
d
       ej$                  j'                  d ee
dz               ddlZdZdZdZdZdZdefdZdedefdZdedefdZdededdfdZedk(  r{ ej                         Z  e!d        e!d        e!de         e!d        e       Z" ee"      Z# ee#e        ej                         e z
  Z$ e!dejJ                   de$d d!       yy)"u  
Venus A-4 (Social Proof) — Meta Carousel Slide
Bright cream/white background, testimonial quote cards with gold accents
Hybrid: Gemini background + Playwright HTML overlay
Output: 1080x1080 PNG → /home/jay/workspace/output/meta-ads/a-group-venus/venus-A4-proof.png
    N)Path)sync_playwright)WORKSPACE_ROOTFONT_DIR
CTA_MIN_PXzoutput/meta-ads/a-group-venusz_bg_venus_a4_proof.jpgz_venus_a4_proof_template.htmlzvenus-A4-proof.pngTparentsexist_okztools/ai-image-genz0https://generativelanguage.googleapis.com/v1betazgemini-3-pro-image-previewzgemini-3.1-flash-image-previewz3https://www.googleapis.com/auth/generative-languageuS	  
Create a warm, serene, light-toned abstract background for a premium Korean insurance team advertisement.

COMPOSITION: 1:1 square, 1080x1080px. Full bleed. No text, no people, no faces.

VISUAL CONCEPT:
A bright, airy cream and off-white background suffused with soft golden light rays gently
streaming downward from the upper area of the canvas. Minimal, clean, and sophisticated.
Like warm morning sunlight filtering through sheer curtains in an elegant space.

BACKGROUND ELEMENTS:
- Warm cream / off-white base (#F5F0E8 to #FAFAF5) — light, airy, and calming
- Soft golden light rays (#C9A84C tones at very low opacity, ~10-15%) streaming diagonally
  from upper-left to center, creating a gentle glow without harshness
_SIZE_26PX = 26
_SIZE_34PX = 34
_CTA_PX = CTA_MIN_PX
_SIZE_44PX = 44
_SIZE_66PX = 66
_SIZE_80PX = 80
_LH_1 = 1
_LH_1_20 = 1.20
_LH_0_65 = 0.65
_LH_1_52 = 1.52
_LH_1_50 = 1.50
- Very subtle warm beige texture — like fine linen or smooth matte paper surface
- Gentle gradient: slightly warmer (more golden-ivory) at center, fading to pure cream at edges
- Top zone (top 20%): slightly lighter/cleaner area for text readability on light background
- Bottom zone: barely perceptible warm ivory shadow, soft and non-distracting
- Overall feel: low-saturation, minimal, photographic quality — background recedes behind content

MOOD / ATMOSPHERE:
- Trust. Transparency. Credibility. Warmth.
- Clean premium consulting feel — trustworthy and human
- "Real results, real people" — intimate and credible, not hype-filled
- Like a bright, beautifully lit minimalist studio where genuine testimonials were shared

COLOR PALETTE:
- Primary base: Warm cream (#F5F0E8), off-white (#FAFAF5), ivory (#F0EBE0)
- Accent glow: Very subtle golden-amber (#C9A84C at 8-12% opacity) as soft light wash
- No dark tones, no navy, no deep shadows
- No cool gray, no blue — pure warm cream/ivory family only
- Maximum luminosity; bright but never harsh or clinical white

STYLE REQUIREMENTS:
- NO stock photography aesthetic
- NO people, faces, hands, or human figures
- NO text, numbers, or labels
- NO dark backgrounds or high contrast zones
- Minimalist, ultra-premium advertising quality — background is supportive, not dominant
- Photographic texture quality — fine, subtle, warm
- The testimonial cards will overlay this background, so keep it clean and uncluttered
returnc            	      b   t         j                         rt        dt                 t         S t        d       t        j                  t
              dt        dt        j                  ffd} t        j                         } | t              }|j                  dv r%t        d|j                   d        | t              }|j                          |j                         }|j                  d	g       }|st!        d
t        |      d d        |d   j                  di       j                  dg       }t#        d |D        d       }|5|D cg c]  }d|v s|j                  dd       }}t!        d|d d        |d   j                  dd      }	|d   d   }
d|	v rdnd}t         j%                  |      }|j'                  t)        j*                  |
             t        d|j,                   d|j/                         j0                  ddt        j                         |z
  dd        |S c c}w )!Nu(   [BG] 기존 배경 이미지 재사용: u1   [BG] Gemini API로 배경 이미지 생성 중...model_idr   c                     t          d|  d}d dd}ddt        igigdd	d
gid}t        j                  |||d      S )Nz/models/z:generateContentzBearer zapplication/json)AuthorizationzContent-TypepartstextresponseModalitiesIMAGETEXT)contentsgenerationConfig,  )headersjsontimeout)GEMINI_API_BASE	BG_PROMPTrequestspost)r   urlr   payloadtokens       V/home/jay/workspace/.worktrees/task-2116-dev1/tools/ai-image-gen/gen_venus_a4_proof.py_callz"generate_background.<locals>._callb   sk     !(3CD&ug..

 "VY$7#89:!57H I
 }}S'MM    )i  i  u   [BG] Pro 모델 실패 (HTTP u   ), fallback 시도...
candidatesu   candidates 없음: r   r   contentr   c              3   *   K   | ]  }d |v s|  yw)
inlineDataN ).0ps     r"   	<genexpr>z&generate_background.<locals>.<genexpr>{   s     ;1):Q;s   	r    u$   이미지 없음. 텍스트 응답:    r(   mimeTypez
image/jpegdatajpegz.jpgz.pngu   [BG] 완료:  (,z bytes, .1fu   초))BG_PATHexistsprintgcloud_authget_service_account_tokenSCOPEstrr   ResponsetimeMODEL_PRIMARYstatus_codeMODEL_FALLBACKraise_for_statusr   getRuntimeErrornextwith_suffixwrite_bytesbase64	b64decodenamestatst_size)r#   t0respr0   r%   r   img_partr+   textsmimeb64extfpathr!   s                @r"   generate_backgroundrT   Z   s   ~~8	BC	
=>11%8E
N 
N 1 1 
N 
BD:%-d.>.>-??TUV^$99;D,+J0T4C0ABCCqMi,00"=E;;TBH,1AqVq[vr"AAA%)MNN\"&&z<@D\"6*CnF&C$E	f&&s+,	M%**R

(<(<Q'?x		TVWZG[[_
`aL Bs   	H,H,bg_pathc                    d| j                          }t        t              }dj                  g d| d| d| d| d| d| d	| d
| dt         dt
         dt         dt
         dt         dt         dt         dt
         dt         dt         dt
         dt         dt
         d      S )Nfile://r-   z<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<style>
  @font-face {
    font-family: 'Pretendard';
    src: url('file://z/PretendardVariable.ttf') format('truetype');
    font-weight: 100 900;
  }
  @font-face {
    font-family: 'Pretendard';
    src: url('file://z/Pretendard-Black.otf') format('opentype');
    font-weight: 900;
  }
  @font-face {
    font-family: 'Pretendard';
    src: url('file://z/Pretendard-ExtraBold.otf') format('opentype');
    font-weight: 800;
  }
  @font-face {
    font-family: 'Pretendard';
    src: url('file://z/Pretendard-Bold.otf') format('opentype');
    font-weight: 700;
  }
  @font-face {
    font-family: 'Pretendard';
    src: url('file://z/Pretendard-Medium.otf') format('opentype');
    font-weight: 500;
  }
  @font-face {
    font-family: 'Pretendard';
    src: url('file://z/Pretendard-Regular.otf') format('opentype');
    font-weight: 400;
  }
  @font-face {
    font-family: 'Pretendard';
    src: url('file://u~  /Pretendard-Light.otf') format('opentype');
    font-weight: 300;
  }

  * { margin: 0; padding: 0; box-sizing: border-box; }

  html, body {
    width: 1080px;
    height: 1080px;
    overflow: hidden;
    background: #F5F0E8;
  }

  /* ── Canvas: background image ── */
  .canvas {
    width: 1080px;
    height: 1080px;
    position: relative;
    background-image: url('u  ');
    background-size: cover;
    background-position: center center;
    font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    overflow: hidden;
  }

  /* ── Light overlay: very subtle warm glow, preserves bright background ── */
  .overlay {
    position: absolute;
    inset: 0;
    background:
      radial-gradient(ellipse 65% 50% at 50% 45%, rgba(201, 168, 76, 0.06) 0%, transparent 65%),
      linear-gradient(
        180deg,
        rgba(255, 252, 245, 0.08) 0%,
        rgba(255, 252, 240, 0.04) 30%,
        rgba(245, 240, 230, 0.04) 70%,
        rgba(240, 235, 220, 0.10) 100%
      );
    pointer-events: none;
  }

  /* All content above overlay */
  .content {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    padding: 52px 68px 52px 68px;
  }

  /* ── TOP ZONE ── */
  .top-zone {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 80px;
    flex-shrink: 0;
    margin-bottom: 20px;
  }

  .brand-badge {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    border: 1.5px solid rgba(160, 120, 40, 0.50);
    border-radius: 6px;
    padding: 8px 18px;
    background: rgba(255, 255, 255, 0.80);
  }

  .badge-dot {
    width: 7px;
    height: 7px;
    background: #A07828;
    border-radius: 50%;
    flex-shrink: 0;
    box-shadow: 0 0 6px rgba(160, 120, 40, 0.7);
  }

  .badge-text {
    font-weight: 700;
    font-size: zEpx;
    color: #A07828;
    letter-spacing: 0.04em;
    line-height: u   ;
  }

  /* ── HEADLINE ── */
  .headline-zone {
    flex-shrink: 0;
    margin-bottom: 28px;
  }

  .headline {
    font-size: z+px;
    font-weight: 800;
    line-height: u%  .20;
    letter-spacing: -0.026em;
    color: #1A0E00;
    word-break: keep-all;
    text-shadow: none;
  }

  .headline .gold {
    color: #A07828;
    font-weight: 900;
  }

  /* ── QUOTE CARDS ZONE ── */
  .cards-zone {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 22px;
    justify-content: center;
    min-height: 0;
  }

  /* Premium testimonial card on bright background */
  .quote-card {
    background: rgba(255, 255, 255, 0.92);
    border: 1.5px solid rgba(160, 120, 40, 0.45);
    border-radius: 14px;
    padding: 30px 36px 30px 48px;
    position: relative;
    box-shadow:
      0 4px 20px rgba(0,0,0,0.09),
      0 1px 4px rgba(160, 120, 40, 0.10);
  }

  /* Left dark gold vertical accent bar */
  .quote-card::before {
    content: '';
    position: absolute;
    left: 0;
    top: 14px;
    bottom: 14px;
    width: 5px;
    background: linear-gradient(180deg, #A07828 0%, rgba(160, 120, 40, 0.35) 100%);
    border-radius: 0 3px 3px 0;
  }

  /* Large decorative quote mark */
  .quote-mark {
    font-size: zPpx;
    font-weight: 900;
    color: rgba(160, 120, 40, 0.22);
    line-height: z;
    float: left;
    margin-right: 12px;
    margin-top: 4px;
    font-family: 'Georgia', serif;
  }

  .quote-body {
    font-size: z+px;
    font-weight: 600;
    line-height: a  .52;
    color: #1A0E00;
    letter-spacing: -0.016em;
    word-break: keep-all;
    display: block;
    overflow: hidden;
  }

  .quote-attribution {
    margin-top: 14px;
    display: flex;
    align-items: center;
    gap: 12px;
    clear: both;
  }

  .attr-line {
    width: 28px;
    height: 1.5px;
    background: rgba(160, 120, 40, 0.55);
    flex-shrink: 0;
  }

  .attr-name {
    font-size: u  px;
    font-weight: 700;
    color: #A07828;
    letter-spacing: 0.04em;
  }

  /* ── BOTTOM ZONE ── */
  .bottom-zone {
    flex-shrink: 0;
    margin-top: 24px;
  }

  .bottom-divider {
    width: 100%;
    height: 1px;
    background: linear-gradient(90deg, rgba(160, 120, 40, 0.45) 0%, rgba(160, 120, 40, 0.04) 100%);
    margin-bottom: 18px;
  }

  .bottom-row {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
  }

  .bottom-attribution {
    font-size: zkpx;
    font-weight: 400;
    color: rgba(60, 50, 30, 0.60);
    letter-spacing: -0.01em;
    line-height: z.50;
    font-style: italic;
    word-break: keep-all;
    flex: 1;
  }

  .bottom-attribution .brand-name {
    color: #A07828;
    font-style: normal;
    font-weight: 700;
  }

  .page-indicator {
    font-size: zpx;
    font-weight: 700;
    color: #A07828;
    letter-spacing: 0.06em;
    flex-shrink: 0;
    margin-left: 20px;
    line-height: u'  ;
  }

</style>
</head>
<body>
<div class="canvas">

  <!-- Warm overlay -->
  <div class="overlay"></div>

  <!-- Content layer -->
  <div class="content">

    <!-- TOP: Brand badge -->
    <div class="top-zone">
      <div class="brand-badge">
        <div class="badge-dot"></div>
        <span class="badge-text">서울대보험쌤</span>
      </div>
    </div>

    <!-- HEADLINE -->
    <div class="headline-zone">
      <h1 class="headline">
        방법을 바꾼 사람들이 말하는<br><span class="gold">실제 변화.</span>
      </h1>
    </div>

    <!-- QUOTE CARDS -->
    <div class="cards-zone">

      <!-- Card 1 -->
      <div class="quote-card">
        <div class="quote-mark">&ldquo;</div>
        <div class="quote-body">거절이 두려웠는데,<br>이제는 고객을 선택합니다.</div>
        <div class="quote-attribution">
          <div class="attr-line"></div>
          <span class="attr-name">이○○</span>
        </div>
      </div>

      <!-- Card 2 -->
      <div class="quote-card">
        <div class="quote-mark">&ldquo;</div>
        <div class="quote-body">자동 유입 시스템으로<br>걱정 없는 영업이 됐습니다.</div>
        <div class="quote-attribution">
          <div class="attr-line"></div>
          <span class="attr-name">김○○</span>
        </div>
      </div>

    </div>

    <!-- BOTTOM: Attribution + Page indicator -->
    <div class="bottom-zone">
      <div class="bottom-divider"></div>
      <div class="bottom-row">
        <p class="bottom-attribution">
          <span class="brand-name">서울대보험쌤 팀</span>의 5가지 시스템 안에서 시작한 이야기입니다.
        </p>
        <div class="page-indicator">4/5</div>
      </div>
    </div>

  </div><!-- /content -->
</div><!-- /canvas -->
</body>
</html>)resolver;   r   join
_SIZE_26PX_LH_1
_SIZE_66PX
_SIZE_80PX_LH_0_65
_SIZE_44PX
_SIZE_34PX_CTA_PX)rU   bg_urlfont_dirs      r"   
build_htmlrd      su   w()*F8}HO O  O ZO O ZO O" Z#O" #O, Z-O, -O6 Z7O6 7O@ ZAO@ AOJ ZKOJ KOn #8oOn?$oOl |mOlmOr sOr
sOF |GOFGOJ KOJ0KOj |kOjkOp qOpqO@ |AO@AOD EODEOt |uOtuOh |iOhiOp qOpqOJ yKOJKOV WOVDWO Or$   c                 v    t        |       }t        j                  |d       t        dt                t        S )Nzutf-8)encodingu   [HTML] 오버레이 저장: )rd   	HTML_PATH
write_textr7   )rU   html_contents     r"   
write_htmlrj     s5    g&L8	(
45r$   	html_pathout_pathc           
      n   t        d       t               5 }|j                  j                         }	 |j	                  ddd      }|j                  d| j                          d       |j                  d       |j                  d	       |j                  j                  d
d
       |j                  t        |      dddddd       |j                          	 d d d        |j                         j                  dz  }t        d| d|dd       y # |j                          w xY w# 1 sw Y   OxY w)Nu$   [RENDER] Playwright 캡처 시작...i8  )widthheight)viewportrW   networkidle)
wait_untilz+async () => { await document.fonts.ready; }i	  Tr   pngr   )xyrn   ro   )pathtypeclipi   u   [RENDER] 완료: r2   z.0fz KB))r7   r   chromiumlaunchnew_pagegotorX   evaluatewait_for_timeoutparentmkdir
screenshotr;   closerJ   rK   )rk   rl   r+   browserpagesize_kbs         r"   capturer     s   	
01		 a**##%	##tt-L#MDII	 1 1 345-IPMMGH!!$'OO!!$!>OO]1ttD   MMO  mmo%%,G	hZr'#d
;< MMO s#   D+BDD+D((D++D4__main__z<============================================================u=   Venus A-4 (Social Proof) — 하이브리드 이미지 생성u   출력: u
   
[완료] z  (r4   u   초 총 소요))&__doc__rG   sysr=   pathlibr   r   playwright.sync_apir   
gen_configr   r   r   
OUTPUT_DIRr5   rg   OUT_PATHr   rv   insertr;   r8   r   r>   r@   r:   r   rT   rd   rj   r   __name__t_startr7   bghtmlelapsedrI   r)   r$   r"   <module>r      s    
    / ; ; ==
2299	.. 
    - 3~(<<= > D.2G4	p,T ,bS S Sl
  =t =t = =0 zdiikG	(O	
IJ	HXJ
 	(O		Bb>DD(diikG#G	Kc'#o
FG r$   