
    iQ                         d Z ddlZddlmZ ddlmZ  ed      Zd Zd Zd Z	d	e
d
ededefdZdedefdZd Zedk(  r ej                    e              yy)uz   
Google Display Ad Generator - Angle C (위기감/긴급성)
Design #17: 숫자 뉴스플래시 - Breaking News Aesthetic
    N)Path)Imagez8/home/jay/workspace/output/google-ads/angle-C/productionc                       y)Nu  <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700;900&display=swap" rel="stylesheet">
<style>
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body {
    width: 1200px;
    height: 628px;
    background: #1A1A1A;
    font-family: 'Noto Sans KR', sans-serif;
    overflow: hidden;
    position: relative;
  }

  /* Subtle texture overlay */
  body::before {
    content: '';
    position: absolute;
    inset: 0;
    background: repeating-linear-gradient(
      0deg,
      transparent,
      transparent 2px,
      rgba(255,255,255,0.012) 2px,
      rgba(255,255,255,0.012) 4px
    );
    z-index: 0;
  }

  /* Red top banner */
  .red-banner {
    position: relative;
    z-index: 10;
    width: 100%;
    height: 62px;
    background: #E60012;
    display: flex;
    align-items: center;
    padding: 0 40px;
    gap: 20px;
  }

  .breaking-dot {
    width: 14px;
    height: 14px;
    background: #fff;
    border-radius: 50%;
    animation: blink 1s infinite;
    flex-shrink: 0;
  }

  .breaking-label {
    font-size: 28px;
    font-weight: 900;
    color: #fff;
    letter-spacing: 0.15em;
    text-transform: uppercase;
  }

  .banner-divider {
    width: 2px;
    height: 28px;
    background: rgba(255,255,255,0.5);
    flex-shrink: 0;
  }

  .banner-sub {
    font-size: 22px;
    font-weight: 700;
    color: rgba(255,255,255,0.9);
    letter-spacing: 0.05em;
  }

  .banner-date {
    margin-left: auto;
    font-size: 20px;
    font-weight: 400;
    color: rgba(255,255,255,0.75);
    letter-spacing: 0.08em;
  }

  /* Main content area */
  .main-content {
    position: relative;
    z-index: 5;
    padding: 38px 60px 0 60px;
    display: flex;
    flex-direction: column;
    gap: 0;
  }

  /* Headline */
  .headline {
    font-size: 92px;
    font-weight: 900;
    color: #FFFFFF;
    line-height: 1.0;
    letter-spacing: -0.02em;
    margin-bottom: 16px;
    text-shadow: 0 2px 20px rgba(0,0,0,0.5);
  }

  /* Layout row: number + sub stacked */
  .info-row {
    display: flex;
    align-items: flex-start;
    gap: 40px;
    margin-bottom: 0;
  }

  .date-block {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
  }

  .date-label {
    font-size: 18px;
    font-weight: 700;
    color: #E60012;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    margin-bottom: 4px;
  }

  .date-number {
    font-size: 96px;
    font-weight: 900;
    color: #FFFFFF;
    line-height: 0.95;
    letter-spacing: -0.03em;
    text-shadow: 0 0 40px rgba(230,0,18,0.3);
  }

  .vertical-divider {
    width: 3px;
    height: 110px;
    background: linear-gradient(to bottom, #E60012, rgba(230,0,18,0.1));
    margin-top: 14px;
    flex-shrink: 0;
  }

  .right-block {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-top: 16px;
  }

  .rule-text {
    font-size: 66px;
    font-weight: 900;
    color: #FFFFFF;
    line-height: 1.05;
    letter-spacing: -0.01em;
  }

  .rule-muted {
    font-size: 32px;
    font-weight: 400;
    color: rgba(255,255,255,0.55);
    margin-top: 6px;
    letter-spacing: 0.04em;
  }

  /* Bottom CTA bar */
  .cta-bar {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 10;
    height: 72px;
    background: linear-gradient(90deg, #111111 0%, #1E1E1E 100%);
    border-top: 3px solid #E60012;
    display: flex;
    align-items: center;
    padding: 0 60px;
    gap: 24px;
  }

  .cta-brand {
    font-size: 30px;
    font-weight: 900;
    color: #E60012;
    letter-spacing: 0.05em;
  }

  .cta-divider {
    width: 2px;
    height: 30px;
    background: rgba(255,255,255,0.25);
  }

  .cta-action {
    font-size: 28px;
    font-weight: 700;
    color: rgba(255,255,255,0.9);
    letter-spacing: 0.03em;
  }

  .cta-arrow {
    margin-left: auto;
    width: 48px;
    height: 48px;
    background: #E60012;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    color: white;
    font-weight: 900;
  }

  /* Decorative elements */
  .deco-line {
    position: absolute;
    right: 0;
    top: 62px;
    bottom: 72px;
    width: 4px;
    background: linear-gradient(to bottom, #E60012, transparent 60%);
    z-index: 3;
  }

  .deco-corner {
    position: absolute;
    bottom: 72px;
    right: 60px;
    width: 120px;
    height: 120px;
    border-right: 3px solid rgba(230,0,18,0.15);
    border-bottom: 3px solid rgba(230,0,18,0.15);
    z-index: 2;
  }

  /* Urgency badge */
  .urgency-badge {
    position: absolute;
    right: 60px;
    top: 120px;
    background: rgba(230,0,18,0.12);
    border: 2px solid rgba(230,0,18,0.4);
    border-radius: 8px;
    padding: 12px 20px;
    text-align: center;
    z-index: 10;
  }

  .badge-line1 {
    font-size: 22px;
    font-weight: 700;
    color: rgba(255,255,255,0.6);
    letter-spacing: 0.05em;
  }

  .badge-line2 {
    font-size: 40px;
    font-weight: 900;
    color: #FF3344;
    letter-spacing: 0.02em;
    line-height: 1.1;
  }

  .badge-line3 {
    font-size: 20px;
    font-weight: 400;
    color: rgba(255,255,255,0.5);
    letter-spacing: 0.04em;
    margin-top: 2px;
  }

  @keyframes blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.3; }
  }
</style>
</head>
<body>
  <!-- Red top banner -->
  <div class="red-banner">
    <div class="breaking-dot"></div>
    <div class="breaking-label">긴급 안내</div>
    <div class="banner-divider"></div>
    <div class="banner-sub">BREAKING NEWS</div>
    <div class="banner-date">2026. 03. 29</div>
  </div>

  <!-- Decorative elements -->
  <div class="deco-line"></div>
  <div class="deco-corner"></div>

  <!-- Urgency badge (right side) -->
  <div class="urgency-badge">
    <div class="badge-line1">시행까지</div>
    <div class="badge-line2">D-90</div>
    <div class="badge-line3">지금이 마지막 기회</div>
  </div>

  <!-- Main content -->
  <div class="main-content">
    <div class="headline">보험 시장 대격변</div>
    <div class="info-row">
      <div class="date-block">
        <div class="date-label">▶ 시행일</div>
        <div class="date-number">2026.7월</div>
      </div>
      <div class="vertical-divider"></div>
      <div class="right-block">
        <div class="rule-text">1,200% 룰 시행 예정</div>
        <div class="rule-muted">보험업법 시행령 개정안</div>
      </div>
    </div>
  </div>

  <!-- Bottom CTA bar -->
  <div class="cta-bar">
    <div class="cta-brand">T.O.P 사업단</div>
    <div class="cta-divider"></div>
    <div class="cta-action">지금 확인하기</div>
    <div class="cta-arrow">▶</div>
  </div>
</body>
</html> r       H/home/jay/workspace/output/google-ads/angle-C/production/generate_ads.pyhtml_1200x628r	      s    Hr   c                       y)Nu  <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700;900&display=swap" rel="stylesheet">
<style>
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body {
    width: 1200px;
    height: 1200px;
    background: #1A1A1A;
    font-family: 'Noto Sans KR', sans-serif;
    overflow: hidden;
    position: relative;
  }

  /* Scanline texture */
  body::before {
    content: '';
    position: absolute;
    inset: 0;
    background: repeating-linear-gradient(
      0deg,
      transparent,
      transparent 3px,
      rgba(255,255,255,0.01) 3px,
      rgba(255,255,255,0.01) 6px
    );
    z-index: 0;
  }

  /* Radial glow from center */
  body::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 900px;
    height: 900px;
    background: radial-gradient(ellipse, rgba(230,0,18,0.06) 0%, transparent 70%);
    z-index: 0;
  }

  /* Red top banner */
  .red-banner {
    position: relative;
    z-index: 10;
    width: 100%;
    height: 80px;
    background: #E60012;
    display: flex;
    align-items: center;
    padding: 0 50px;
    gap: 24px;
  }

  .breaking-dot {
    width: 16px;
    height: 16px;
    background: #fff;
    border-radius: 50%;
    flex-shrink: 0;
  }

  .breaking-label {
    font-size: 34px;
    font-weight: 900;
    color: #fff;
    letter-spacing: 0.18em;
  }

  .banner-divider {
    width: 2px;
    height: 34px;
    background: rgba(255,255,255,0.45);
    flex-shrink: 0;
  }

  .banner-sub {
    font-size: 26px;
    font-weight: 700;
    color: rgba(255,255,255,0.88);
    letter-spacing: 0.08em;
  }

  .banner-date {
    margin-left: auto;
    font-size: 22px;
    font-weight: 400;
    color: rgba(255,255,255,0.7);
    letter-spacing: 0.06em;
  }

  /* Content wrapper */
  .content {
    position: relative;
    z-index: 5;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 60px 70px 0 70px;
    text-align: center;
    height: calc(1200px - 80px - 90px);
  }

  /* Headline */
  .headline {
    font-size: 96px;
    font-weight: 900;
    color: #FFFFFF;
    line-height: 1.0;
    letter-spacing: -0.02em;
    margin-bottom: 50px;
    text-shadow: 0 2px 30px rgba(0,0,0,0.6);
  }

  /* Middle divider */
  .mid-divider {
    width: 80px;
    height: 4px;
    background: #E60012;
    margin-bottom: 50px;
  }

  /* Date focal point */
  .date-section {
    margin-bottom: 30px;
  }

  .date-label {
    font-size: 24px;
    font-weight: 700;
    color: #E60012;
    letter-spacing: 0.2em;
    margin-bottom: 10px;
  }

  .date-number {
    font-size: 130px;
    font-weight: 900;
    color: #FFFFFF;
    line-height: 0.9;
    letter-spacing: -0.03em;
    text-shadow:
      0 0 60px rgba(230,0,18,0.25),
      0 4px 30px rgba(0,0,0,0.5);
  }

  /* Rule text */
  .rule-section {
    margin-bottom: 50px;
  }

  .rule-text {
    font-size: 72px;
    font-weight: 900;
    color: #FFFFFF;
    line-height: 1.1;
    letter-spacing: -0.01em;
    margin-bottom: 12px;
  }

  .rule-sub {
    font-size: 36px;
    font-weight: 400;
    color: rgba(255,255,255,0.5);
    letter-spacing: 0.04em;
  }

  /* Urgency row */
  .urgency-row {
    display: flex;
    align-items: center;
    gap: 28px;
    margin-bottom: 0;
  }

  .urgency-line {
    flex: 1;
    height: 2px;
    background: linear-gradient(90deg, transparent, rgba(230,0,18,0.4));
  }

  .urgency-line.right {
    background: linear-gradient(90deg, rgba(230,0,18,0.4), transparent);
  }

  .urgency-text {
    font-size: 44px;
    font-weight: 700;
    color: #FF4455;
    letter-spacing: 0.05em;
  }

  /* Bottom CTA bar */
  .cta-bar {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 10;
    height: 90px;
    background: #111111;
    border-top: 4px solid #E60012;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 28px;
  }

  .cta-brand {
    font-size: 36px;
    font-weight: 900;
    color: #E60012;
    letter-spacing: 0.08em;
  }

  .cta-divider {
    width: 2px;
    height: 36px;
    background: rgba(255,255,255,0.25);
  }

  .cta-action {
    font-size: 34px;
    font-weight: 700;
    color: rgba(255,255,255,0.9);
    letter-spacing: 0.04em;
  }

  /* Decorative corner lines */
  .corner-tl, .corner-tr, .corner-bl, .corner-br {
    position: absolute;
    z-index: 6;
    width: 50px;
    height: 50px;
  }

  .corner-tl {
    top: 100px;
    left: 30px;
    border-top: 2px solid rgba(230,0,18,0.3);
    border-left: 2px solid rgba(230,0,18,0.3);
  }

  .corner-tr {
    top: 100px;
    right: 30px;
    border-top: 2px solid rgba(230,0,18,0.3);
    border-right: 2px solid rgba(230,0,18,0.3);
  }

  .corner-bl {
    bottom: 110px;
    left: 30px;
    border-bottom: 2px solid rgba(230,0,18,0.3);
    border-left: 2px solid rgba(230,0,18,0.3);
  }

  .corner-br {
    bottom: 110px;
    right: 30px;
    border-bottom: 2px solid rgba(230,0,18,0.3);
    border-right: 2px solid rgba(230,0,18,0.3);
  }
</style>
</head>
<body>
  <!-- Red top banner -->
  <div class="red-banner">
    <div class="breaking-dot"></div>
    <div class="breaking-label">긴급 안내</div>
    <div class="banner-divider"></div>
    <div class="banner-sub">BREAKING NEWS</div>
    <div class="banner-date">2026. 03. 29</div>
  </div>

  <!-- Corner decorations -->
  <div class="corner-tl"></div>
  <div class="corner-tr"></div>
  <div class="corner-bl"></div>
  <div class="corner-br"></div>

  <!-- Main content -->
  <div class="content">
    <div class="headline">보험 시장 대격변</div>
    <div class="mid-divider"></div>

    <div class="date-section">
      <div class="date-label">▶ 시행일</div>
      <div class="date-number">2026.7월</div>
    </div>

    <div class="rule-section">
      <div class="rule-text">1,200% 룰 시행 예정</div>
      <div class="rule-sub">보험업법 시행령 개정안</div>
    </div>

    <div class="urgency-row">
      <div class="urgency-line"></div>
      <div class="urgency-text">지금이 마지막 기회</div>
      <div class="urgency-line right"></div>
    </div>
  </div>

  <!-- Bottom CTA bar -->
  <div class="cta-bar">
    <div class="cta-brand">T.O.P 사업단</div>
    <div class="cta-divider"></div>
    <div class="cta-action">지금 확인하기</div>
  </div>
</body>
</html>r   r   r   r   html_1200x1200r   ]  s    {r   c                       y)z.Renders at 600x500, will be resized to 300x250u  <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700;900&display=swap" rel="stylesheet">
<style>
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body {
    width: 600px;
    height: 500px;
    background: #1A1A1A;
    font-family: 'Noto Sans KR', sans-serif;
    overflow: hidden;
    position: relative;
  }

  body::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 500px;
    height: 500px;
    background: radial-gradient(ellipse, rgba(230,0,18,0.08) 0%, transparent 70%);
    z-index: 0;
  }

  /* Red top banner */
  .red-banner {
    position: relative;
    z-index: 10;
    width: 100%;
    height: 48px;
    background: #E60012;
    display: flex;
    align-items: center;
    padding: 0 20px;
    gap: 12px;
  }

  .breaking-dot {
    width: 10px;
    height: 10px;
    background: #fff;
    border-radius: 50%;
    flex-shrink: 0;
  }

  .breaking-label {
    font-size: 20px;
    font-weight: 900;
    color: #fff;
    letter-spacing: 0.15em;
  }

  .banner-divider {
    width: 1px;
    height: 20px;
    background: rgba(255,255,255,0.45);
    flex-shrink: 0;
  }

  .banner-sub {
    font-size: 14px;
    font-weight: 700;
    color: rgba(255,255,255,0.85);
    letter-spacing: 0.08em;
  }

  /* Main content */
  .content {
    position: relative;
    z-index: 5;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 24px 30px 0 30px;
  }

  .headline {
    font-size: 52px;
    font-weight: 900;
    color: #FFFFFF;
    line-height: 1.0;
    letter-spacing: -0.02em;
    margin-bottom: 16px;
  }

  .red-rule {
    width: 50px;
    height: 3px;
    background: #E60012;
    margin-bottom: 16px;
  }

  .date-label {
    font-size: 14px;
    font-weight: 700;
    color: #E60012;
    letter-spacing: 0.15em;
    margin-bottom: 4px;
  }

  .date-number {
    font-size: 76px;
    font-weight: 900;
    color: #FFFFFF;
    line-height: 0.92;
    letter-spacing: -0.02em;
    text-shadow: 0 0 40px rgba(230,0,18,0.3);
    margin-bottom: 16px;
  }

  .rule-text {
    font-size: 40px;
    font-weight: 900;
    color: #FFFFFF;
    line-height: 1.1;
    letter-spacing: -0.01em;
    margin-bottom: 8px;
  }

  .urgency-text {
    font-size: 26px;
    font-weight: 700;
    color: #FF4455;
    letter-spacing: 0.04em;
  }

  /* Bottom CTA */
  .cta-bar {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 10;
    height: 60px;
    background: #111111;
    border-top: 3px solid #E60012;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
  }

  .cta-brand {
    font-size: 22px;
    font-weight: 900;
    color: #E60012;
    letter-spacing: 0.06em;
  }

  .cta-divider {
    width: 1px;
    height: 22px;
    background: rgba(255,255,255,0.25);
  }

  .cta-action {
    font-size: 20px;
    font-weight: 700;
    color: rgba(255,255,255,0.88);
  }
</style>
</head>
<body>
  <!-- Red top banner -->
  <div class="red-banner">
    <div class="breaking-dot"></div>
    <div class="breaking-label">긴급 안내</div>
    <div class="banner-divider"></div>
    <div class="banner-sub">BREAKING NEWS</div>
  </div>

  <!-- Main content -->
  <div class="content">
    <div class="headline">보험 시장 대격변</div>
    <div class="red-rule"></div>
    <div class="date-label">▶ 시행일</div>
    <div class="date-number">2026.7월</div>
    <div class="rule-text">1,200% 룰 시행 예정</div>
    <div class="urgency-text">지금이 마지막 기회</div>
  </div>

  <!-- Bottom CTA -->
  <div class="cta-bar">
    <div class="cta-brand">T.O.P 사업단</div>
    <div class="cta-divider"></div>
    <div class="cta-action">지금 확인하기</div>
  </div>
</body>
</html>r   r   r   r   html_600x500r     s    Cr   html_contentwidthheightoutput_pathc           
        K   ddl m}  |       4 d {   }|j                  j                  dg       d {   }|j	                  ||d       d {   }|j
                  d|j                   dz  }|j                  | d	
       |j                  d| d       d {    |j                  d       d {    |j                  t        |      d       d {    |j                          d {    |j                  d       t        d|j                   d| d| d       d d d       d {    y 7 ,7 
7 7 7 7 j7 T7 # 1 d {  7  sw Y   y xY ww)Nr   )async_playwrightz--no-sandbox)args)r   r   )viewport_tmp_z.htmlzutf-8)encodingzfile://networkidle)
wait_untili  F)path	full_pageT
missing_oku     ✓ Rendered: z (x))playwright.async_apir   chromiumlaunchnew_pageparentname
write_textgotowait_for_timeout
screenshotstrcloseunlinkprint)	r   r   r   r   r   pbrowserpagetmp_paths	            r   render_htmlr2   h  s_    5! H HQ

))/?)@@%%&/Q%RR %%%0@0@/A(GGL7;ii'(,iGGG##D)))oo3{#3uoEEEmmo4( !1!1 2"UG1VHAFGH H H@R 	H)EH H H Hs   E'E E'!EEEEAE$E%E=E
>#E!E"E9E:5E/E':E;E'EEE
EEEE'E$EE$ E'src_pathdst_pathc                     t        j                  |       }|j                  dt         j                        }|j	                  |dd       t        d|j                   d       y)u>   Resize 600x500 → 300x250 using PIL with high-quality Lanczos)i,     PNGT)optimizeu     ✓ Resized: z
 (300x250)N)r   openresizeLANCZOSsaver-   r%   )r3   r4   imgresizeds       r   resize_to_300x250r?   }  sK    
**X
CjjU]]3GLL54L0	OHMM?*
56r   c                    K   t        d       t        d       t        j                  dd       t        d       t        dz  } t        t	               dd|        d {    t        d	       t        d
z  }t        t               dd|       d {    t        d       t        dz  }t        dz  }t        t               dd|       d {    t        ||       |j                  d       t        d       t        t        j                  d            D ];  }|j                         j                  dz  }t        d|j                   d| d       = t        dt                y 7 
7 7 w)Nz-
=== Google Display Ad Generator: Angle C ===u=   Design: #17 숫자 뉴스플래시 (Breaking News Aesthetic)
T)parentsexist_okz&[1/3] Generating 1200x628 landscape...zdisplay-1200x628.pngi  it  z$[2/3] Generating 1200x1200 square...zdisplay-1200x1200.pngz<[3/3] Generating 300x250 (render at 600x500, then resize)...z_tmp_600x500.pngzdisplay-300x250.pngiX  i  r   z(
=== All ads generated successfully! ===zdisplay-*.pngi   z  z: KBz
Output directory: )r-   
OUTPUT_DIRmkdirr2   r	   r   r   r?   r,   sortedglobstatst_sizer%   )path_1200x628path_1200x1200path_600x500_tmppath_300x250fsize_kbs         r   mainrP     sV    	
:;	
JKTD1 

23!77M
motS-
@@@ 

01"99N
n&dN
CCC 

HI!$66 55L
lnc30@
AAA&5t,	
56JOOO45 *&&(""d*166("WIR()* 
 
-.' A
 D Bs7   AE.E'1E.E*:E.
E,BE.*E.,E.__main__)__doc__asynciopathlibr   PILr   rD   r	   r   r   r*   intr2   r?   rP   __name__runr   r   r   <module>rY      s   
   LM
IX
|~	EXHC H HS Ht H*7 7 7/> zGKK r   