Загрузка данных


"""
СИМУЛЯТОР ШАУРМИСТА — RELEASE BUILD v1.1
Герои: Камаладдин и Оглы
Один файл. Вся графика рисуется кодом.
"""
import pygame, sys, random, math, json, os

pygame.init()
W, H = 1280, 720
screen = pygame.display.set_mode((W, H))
pygame.display.set_caption("Симулятор Шаурмиста: Камаладдин и Оглы")
clock = pygame.time.Clock()

# ============================== ШРИФТЫ ==============================
font_xs = pygame.font.SysFont("consolas", 12)
font_s  = pygame.font.SysFont("consolas", 15)
font_m  = pygame.font.SysFont("consolas", 19, bold=True)
font_l  = pygame.font.SysFont("consolas", 26, bold=True)
font_xl = pygame.font.SysFont("consolas", 44, bold=True)
font_xxl= pygame.font.SysFont("consolas", 66, bold=True)

# ============================== ЦВЕТА ==============================
C_NIGHT    = (18, 16, 28)
C_BG       = (30, 28, 42)
C_PANEL    = (44, 42, 58)
C_PANEL_D  = (28, 26, 40)
C_PANEL_L  = (60, 58, 78)
C_TEXT     = (242, 236, 220)
C_TEXT_DIM = (160, 156, 145)
C_GOLD     = (248, 200, 80)
C_GOLD_D   = (180, 140, 50)
C_RED      = (230, 80, 80)
C_RED_D    = (150, 40, 40)
C_GREEN    = (110, 210, 120)
C_GREEN_D  = (50, 130, 60)
C_BLUE     = (100, 170, 240)
C_PURPLE   = (170, 120, 220)
C_ORANGE   = (245, 140, 50)
C_SKIN     = (222, 184, 135)
C_SKIN_D   = (180, 140, 95)
C_HAIR     = (40, 30, 25)
C_LAVASH   = (240, 220, 170)
C_TOM      = (220, 70, 60)

# ============================== ИНГРЕДИЕНТЫ ==============================
(I_LAVASH, I_MEAT_C, I_MEAT_B, I_TOMATO, I_CUCUMBER, I_CABBAGE,
 I_ONION, I_CHEESE, I_FRIES, I_SAUCE_G, I_SAUCE_S, I_WRAP) = range(12)

ING_NAME = {
    I_LAVASH:"Лаваш", I_MEAT_C:"Курица", I_MEAT_B:"Говядина",
    I_TOMATO:"Помидор", I_CUCUMBER:"Огурец", I_CABBAGE:"Капуста",
    I_ONION:"Лук", I_CHEESE:"Сыр", I_FRIES:"Картофель фри",
    I_SAUCE_G:"Чесночный", I_SAUCE_S:"Острый", I_WRAP:"Завернуть",
}
ING_SHORT = {
    I_LAVASH:"Лаваш", I_MEAT_C:"Курица", I_MEAT_B:"Говядина",
    I_TOMATO:"Помидор", I_CUCUMBER:"Огурец", I_CABBAGE:"Капуста",
    I_ONION:"Лук", I_CHEESE:"Сыр", I_FRIES:"Фри",
    I_SAUCE_G:"Чеснок", I_SAUCE_S:"Острый", I_WRAP:"Завернуть",
}
GRILL_INGS = {I_MEAT_C, I_MEAT_B, I_FRIES}
COOK_TIME  = {I_MEAT_C: 4.0, I_MEAT_B: 6.0, I_FRIES: 3.0}
BURN_TIME  = {I_MEAT_C: 3.5, I_MEAT_B: 4.5, I_FRIES: 2.5}

# ============================== РИСОВАНИЕ ЕДЫ ==============================
def draw_food(surf, ing, x, y, size, cook_state=None):
    cx, cy = x + size // 2, y + size // 2
    r = size // 2 - 3

    if ing == I_LAVASH:
        pygame.draw.ellipse(surf, C_LAVASH, (x+4, y+12, size-8, size-24))
        pygame.draw.ellipse(surf, (200,180,130), (x+4, y+12, size-8, size-24), 2)
        pygame.draw.ellipse(surf, (215,195,150), (x+8, y+16, size-16, size-30))

    elif ing == I_MEAT_C:
        col = (240,210,140)
        if cook_state == "cooked": col = (200,140,60)
        if cook_state == "burned": col = (60,40,30)
        pygame.draw.ellipse(surf, col, (x+8, y+14, size-16, size-28))
        dark = (max(0,col[0]-50), max(0,col[1]-50), max(0,col[2]-50))
        pygame.draw.ellipse(surf, dark, (x+8, y+14, size-16, size-28), 2)
        for i in range(3):
            pygame.draw.line(surf, (250,230,180),
                             (x+16+i*7, y+20), (x+16+i*7, y+size-20), 2)

    elif ing == I_MEAT_B:
        col = (160,70,50)
        if cook_state == "cooked": col = (120,50,30)
        if cook_state == "burned": col = (50,30,25)
        pygame.draw.ellipse(surf, col, (x+8, y+14, size-16, size-28))
        dark = (max(0,col[0]-30), max(0,col[1]-20), max(0,col[2]-20))
        pygame.draw.ellipse(surf, dark, (x+8, y+14, size-16, size-28), 2)
        for i in range(3):
            pygame.draw.line(surf, (200,110,80),
                             (x+16+i*7, y+20), (x+16+i*7, y+size-20), 2)

    elif ing == I_TOMATO:
        pygame.draw.circle(surf, C_TOM, (cx, cy), r-3)
        pygame.draw.circle(surf, (150,25,25), (cx, cy), r-3, 2)
        pygame.draw.circle(surf, (255,130,120), (cx-4, cy-4), 4)

    elif ing == I_CUCUMBER:
        pygame.draw.ellipse(surf, (140,200,100), (cx-10, y+8, 20, size-16))
        pygame.draw.ellipse(surf, (60,130,50), (cx-10, y+8, 20, size-16), 2)
        pygame.draw.circle(surf, (170,220,130), (cx, y+18), 2)
        pygame.draw.circle(surf, (170,220,130), (cx, y+34), 2)

    elif ing == I_CABBAGE:
        pygame.draw.circle(surf, (200,230,180), (cx, cy), r-4)
        for a in range(6):
            ang = a * math.pi / 3
            ex = cx + math.cos(ang) * (r-8)
            ey = cy + math.sin(ang) * (r-8)
            pygame.draw.line(surf, (130,170,100), (cx, cy), (ex, ey), 1)
        pygame.draw.circle(surf, (130,170,100), (cx, cy), r-4, 2)

    elif ing == I_ONION:
        for i, rr in enumerate([r-2, r-8, r-14]):
            col = (230,220,200) if i % 2 == 0 else (210,200,180)
            pygame.draw.arc(surf, col, (cx-rr, cy-rr, rr*2, rr*2), 0, math.pi, 3)
            pygame.draw.arc(surf, col, (cx-rr, cy-rr, rr*2, rr*2), math.pi, 2*math.pi, 3)

    elif ing == I_CHEESE:
        pygame.draw.polygon(surf, (250,210,100), [
            (cx-16, cy+12), (cx+18, cy+12), (cx+18, cy-4), (cx-10, cy-14)])
        pygame.draw.polygon(surf, (200,150,40), [
            (cx-16, cy+12), (cx+18, cy+12), (cx+18, cy-4), (cx-10, cy-14)], 2)
        for dx, dy in [(-4,0),(4,4),(-2,6),(8,-2)]:
            pygame.draw.circle(surf, (230,180,60), (cx+dx, cy+dy), 2)

    elif ing == I_FRIES:
        col = (250,210,130)
        if cook_state == "cooked": col = (250,180,80)
        if cook_state == "burned": col = (90,60,30)
        for i in range(6):
            xx = x + 14 + i * 6
            yy = y + 20 + (i % 2) * 2
            pygame.draw.rect(surf, col, (xx, yy, 4, 24))
        pygame.draw.rect(surf, (200,60,40), (x+12, y+40, size-24, 12))
        pygame.draw.rect(surf, (140,30,20), (x+12, y+40, size-24, 12), 2)

    elif ing == I_SAUCE_G:
        pygame.draw.rect(surf, (240,235,220), (x+14, y+14, size-28, size-24))
        pygame.draw.rect(surf, (170,160,140), (x+14, y+14, size-28, size-24), 2)
        pygame.draw.circle(surf, (200,190,170), (cx, cy-2), 5)

    elif ing == I_SAUCE_S:
        pygame.draw.rect(surf, (220,60,40), (x+14, y+14, size-28, size-24))
        pygame.draw.rect(surf, (140,30,20), (x+14, y+14, size-28, size-24), 2)
        pygame.draw.circle(surf, (255,200,180), (cx, cy-2), 5)

    elif ing == I_WRAP:
        pygame.draw.polygon(surf, C_LAVASH, [
            (x+10, y+size-8), (x+size-10, y+size-8), (cx, y+8)])
        pygame.draw.polygon(surf, (180,160,120), [
            (x+10, y+size-8), (x+size-10, y+size-8), (cx, y+8)], 2)
        pygame.draw.line(surf, (150,130,100), (cx, y+size-14), (cx, y+14), 2)

    pygame.draw.rect(surf, C_PANEL_D, (x, y, size, size), 2)

# ============================== ПЕРСОНАЖИ ==============================
def draw_kama(surf, x, y, scale=1.0, mood="normal", frame=0, action=None):
    s = scale

    def R(c, rect):
        pygame.draw.rect(surf, c,
            (x + int(rect[0]*s), y + int(rect[1]*s),
             max(1, int(rect[2]*s)), max(1, int(rect[3]*s))))

    leg_off = int(math.sin(frame*0.1) * 3) if action == "walk" else 0
    R((50,50,90), (30, 190+leg_off, 22, 40))
    R((50,50,90), (58, 190-leg_off, 22, 40))
    R((30,30,50), (28, 226+leg_off, 26, 10))
    R((30,30,50), (56, 226-leg_off, 26, 10))

    shirt = (70, 100, 180)
    if mood == "sad": shirt = (60, 70, 140)
    R(shirt, (28, 118, 64, 78))
    for i in range(4):
        R((50,80,150), (28, 130+i*16, 64, 3))

    R((240,240,240), (36, 140, 48, 60))
    R((220,220,220), (46, 165, 28, 20))
    R((220,220,220), (36, 115, 48, 6))

    arm_off = int(math.sin(frame*0.15) * 5) if action == "cook" else 0
    R(C_SKIN, (16, 122, 14, 50+arm_off))
    R(C_SKIN_D, (16, 168+arm_off, 14, 8))
    R(C_SKIN, (90, 122, 14, 50-arm_off))
    R(C_SKIN_D, (90, 168-arm_off, 14, 8))

    R(C_SKIN_D, (50, 108, 22, 14))
    pygame.draw.ellipse(surf, C_SKIN,
        (x + int(36*s), y + int(40*s), int(48*s), int(74*s)))
    pygame.draw.ellipse(surf, C_SKIN_D,
        (x + int(36*s), y + int(40*s), int(48*s), int(74*s)), max(1, int(2*s)))

    R(C_SKIN, (32, 68, 8, 12))
    R(C_SKIN, (80, 68, 8, 12))

    pygame.draw.arc(surf, C_HAIR,
        (x + int(32*s), y + int(30*s), int(56*s), int(80*s)),
        0.15, math.pi - 0.15, int(14*s))
    R(C_HAIR, (34, 42, 52, 22))
    R(C_HAIR, (56, 30, 10, 12))

    eye_y = 72
    if mood == "sad":
        R(C_HAIR, (42, eye_y-4, 10, 3))
        R(C_HAIR, (66, eye_y-4, 10, 3))
    elif mood == "happy":
        pygame.draw.arc(surf, C_HAIR,
            (x + int(42*s), y + int(eye_y*s), int(14*s), int(10*s)),
            math.pi, 2*math.pi, max(1, int(3*s)))
        pygame.draw.arc(surf, C_HAIR,
            (x + int(64*s), y + int(eye_y*s), int(14*s), int(10*s)),
            math.pi, 2*math.pi, max(1, int(3*s)))
    elif mood == "surprised":
        pygame.draw.circle(surf, (255,255,255),
            (x + int(48*s), y + int((eye_y+4)*s)), int(7*s))
        pygame.draw.circle(surf, (255,255,255),
            (x + int(72*s), y + int((eye_y+4)*s)), int(7*s))
        pygame.draw.circle(surf, C_HAIR,
            (x + int(48*s), y + int((eye_y+4)*s)), int(3*s))
        pygame.draw.circle(surf, C_HAIR,
            (x + int(72*s), y + int((eye_y+4)*s)), int(3*s))
    else:
        pygame.draw.circle(surf, (255,255,255),
            (x + int(48*s), y + int((eye_y+4)*s)), int(6*s))
        pygame.draw.circle(surf, (255,255,255),
            (x + int(72*s), y + int((eye_y+4)*s)), int(6*s))
        pygame.draw.circle(surf, (30,60,100),
            (x + int(49*s), y + int((eye_y+4)*s)), int(3*s))
        pygame.draw.circle(surf, (30,60,100),
            (x + int(73*s), y + int((eye_y+4)*s)), int(3*s))

    R(C_SKIN_D, (58, eye_y+10, 4, 8))
    R(C_HAIR, (48, eye_y+22, 24, 4))
    R(C_HAIR, (46, eye_y+21, 28, 2))
    R(C_HAIR, (44, eye_y+26, 6, 3))
    R(C_HAIR, (70, eye_y+26, 6, 3))

    if mood == "happy":
        pygame.draw.arc(surf, (120,50,50),
            (x + int(52*s), y + int((eye_y+28)*s), int(20*s), int(10*s)),
            0, math.pi, max(1, int(2*s)))
    elif mood == "sad":
        pygame.draw.arc(surf, (120,50,50),
            (x + int(52*s), y + int((eye_y+34)*s), int(20*s), int(10*s)),
            math.pi, 2*math.pi, max(1, int(2*s)))
    else:
        R((120,50,50), (54, eye_y+32, 16, 2))


def draw_ogly(surf, x, y, scale=1.0, mood="normal", frame=0, action=None):
    s = scale

    def R(c, rect):
        pygame.draw.rect(surf, c,
            (x + int(rect[0]*s), y + int(rect[1]*s),
             max(1, int(rect[2]*s)), max(1, int(rect[3]*s))))

    leg_off = int(math.sin(frame*0.1) * 3) if action == "walk" else 0
    R((40,40,60), (26, 195+leg_off, 26, 42))
    R((40,40,60), (58, 195-leg_off, 26, 42))
    R((20,20,30), (22, 232+leg_off, 32, 10))
    R((20,20,30), (56, 232-leg_off, 32, 10))

    shirt = (150, 60, 60)
    if mood == "sad": shirt = (110, 50, 50)
    R(shirt, (22, 120, 76, 82))
    for i in range(5):
        R((110, 40, 40), (22, 128+i*14, 76, 3))
    pygame.draw.ellipse(surf, shirt,
        (x + int(20*s), y + int(158*s), int(80*s), int(70*s)))
    pygame.draw.ellipse(surf, (110,40,40),
        (x + int(20*s), y + int(158*s), int(80*s), int(70*s)), max(1, int(2*s)))
    for i in range(3):
        R((240,220,180), (58, 135+i*22, 4, 4))

    arm_off = int(math.sin(frame*0.15) * 5) if action == "cook" else 0
    R(C_SKIN, (10, 124, 16, 55+arm_off))
    R(C_SKIN_D, (10, 174+arm_off, 16, 8))
    R(C_SKIN, (94, 124, 16, 55-arm_off))
    R(C_SKIN_D, (94, 174-arm_off, 16, 8))
    R(shirt, (10, 124, 16, 22))
    R(shirt, (94, 124, 16, 22))

    R(C_SKIN_D, (48, 105, 24, 18))
    pygame.draw.ellipse(surf, C_SKIN,
        (x + int(32*s), y + int(30*s), int(56*s), int(82*s)))
    pygame.draw.ellipse(surf, C_SKIN_D,
        (x + int(32*s), y + int(30*s), int(56*s), int(82*s)), max(1, int(2*s)))

    R(C_SKIN, (28, 60, 8, 14))
    R(C_SKIN, (84, 60, 8, 14))

    beard_col = (55, 40, 30)
    pygame.draw.ellipse(surf, beard_col,
        (x + int(34*s), y + int(72*s), int(52*s), int(40*s)))
    pygame.draw.ellipse(surf, beard_col,
        (x + int(40*s), y + int(82*s), int(40*s), int(30*s)))

    eye_y = 62
    if mood == "happy":
        pygame.draw.arc(surf, C_HAIR,
            (x + int(40*s), y + int(eye_y*s), int(14*s), int(10*s)),
            math.pi, 2*math.pi, max(1, int(3*s)))
        pygame.draw.arc(surf, C_HAIR,
            (x + int(66*s), y + int(eye_y*s), int(14*s), int(10*s)),
            math.pi, 2*math.pi, max(1, int(3*s)))
    elif mood == "angry":
        R(C_HAIR, (38, eye_y-6, 16, 4))
        R(C_HAIR, (66, eye_y-6, 16, 4))
        pygame.draw.circle(surf, (255,255,255),
            (x + int(46*s), y + int((eye_y+2)*s)), int(6*s))
        pygame.draw.circle(surf, (255,255,255),
            (x + int(72*s), y + int((eye_y+2)*s)), int(6*s))
        pygame.draw.circle(surf, C_HAIR,
            (x + int(47*s), y + int((eye_y+2)*s)), int(3*s))
        pygame.draw.circle(surf, C_HAIR,
            (x + int(73*s), y + int((eye_y+2)*s)), int(3*s))
    else:
        pygame.draw.circle(surf, (255,255,255),
            (x + int(46*s), y + int((eye_y+2)*s)), int(6*s))
        pygame.draw.circle(surf, (255,255,255),
            (x + int(72*s), y + int((eye_y+2)*s)), int(6*s))
        pygame.draw.circle(surf, C_HAIR,
            (x + int(47*s), y + int((eye_y+2)*s)), int(3*s))
        pygame.draw.circle(surf, C_HAIR,
            (x + int(73*s), y + int((eye_y+2)*s)), int(3*s))

    pygame.draw.ellipse(surf, C_SKIN_D,
        (x + int(56*s), y + int((eye_y+10)*s), int(8*s), int(12*s)))

    cap_col = (55, 60, 85)
    pygame.draw.arc(surf, cap_col,
        (x + int(28*s), y + int(18*s), int(64*s), int(54*s)),
        0, math.pi, int(18*s))
    R(cap_col, (30, 34, 60, 14))
    pygame.draw.ellipse(surf, (40,45,70),
        (x + int(20*s), y + int(36*s), int(30*s), int(12*s)))
    R((100,90,70), (58, 20, 6, 6))


def draw_customer(surf, x, y, seed, mood="normal", frame=0):
    rng = random.Random(seed)
    skin = rng.choice([(235,200,170),(210,170,135),(180,140,100),(150,110,75),(120,85,60)])
    shirt = rng.choice([(200,80,80),(80,140,200),(180,180,80),(140,80,180),
                        (200,140,60),(80,180,140),(60,60,120),(230,90,140),
                        (100,100,100),(200,200,200)])
    pants = rng.choice([(40,40,80),(60,50,40),(20,30,60),(80,60,40)])
    hair_col = rng.choice([(30,20,15),(80,50,30),(200,180,140),(120,80,50),
                           (180,80,40),(60,60,60),(230,220,180)])

    def R(c, rect):
        pygame.draw.rect(surf, c, (x+rect[0], y+rect[1], rect[2], rect[3]))

    R(pants, (22, 160, 20, 40))
    R(pants, (52, 160, 20, 40))
    R((30,30,30), (18, 194, 26, 10))
    R((30,30,30), (50, 194, 26, 10))

    R(shirt, (18, 96, 58, 66))

    arm_sw = int(math.sin(frame*0.08) * 3)
    R(skin, (6, 102+arm_sw, 12, 48))
    R(skin, (76, 102-arm_sw, 12, 48))

    pygame.draw.ellipse(surf, skin, (x+24, y+32, 46, 60))
    pygame.draw.ellipse(surf, tuple(max(0,c-30) for c in skin), (x+24, y+32, 46, 60), 2)
    R(skin, (20, 58, 8, 12))
    R(skin, (66, 58, 8, 12))

    style = rng.randint(0, 5)
    if style == 0:
        pygame.draw.arc(surf, hair_col, (x+22, y+24, 50, 60), 0.1, math.pi-0.1, 10)
        R(hair_col, (24, 32, 46, 10))
    elif style == 1:
        pygame.draw.arc(surf, hair_col, (x+22, y+22, 50, 60), 0.1, math.pi-0.1, 12)
        R(hair_col, (22, 32, 50, 24))
    elif style == 2:
        pygame.draw.arc(surf, hair_col, (x+22, y+30, 50, 60), math.pi, 2*math.pi, 4)
    elif style == 3:
        pygame.draw.arc(surf, hair_col, (x+22, y+24, 50, 60), 0.1, math.pi-0.1, 10)
        R(hair_col, (24, 32, 46, 12))
        R(hair_col, (68, 44, 8, 20))
    elif style == 4:
        R(hair_col, (40, 20, 14, 20))
    else:
        for i in range(6):
            r = 8 + rng.randint(0, 4)
            pygame.draw.circle(surf, hair_col, (32+i*7, 34+((i%2)*4)), r)

    for dx in [0, 24]:
        pygame.draw.circle(surf, (255,255,255), (x+38+dx, y+58), 5)
        pygame.draw.circle(surf, (25,25,40), (x+38+dx, y+58), 3)

    R(tuple(max(0,c-30) for c in skin), (44, 68, 6, 6))

    if mood == "happy":
        pygame.draw.arc(surf, (120,50,50), (x+38, y+76, 20, 10), 0, math.pi, 2)
    elif mood == "angry":
        R((120,50,50), (40, 82, 16, 2))
    else:
        R((120,50,50), (42, 80, 12, 2))

# ============================== ЧАСТИЦЫ ==============================
class Particle:
    def __init__(self, x, y, vx, vy, life, color, size=3, gravity=0.2, glow=False, text=None):
        self.x, self.y, self.vx, self.vy = x, y, vx, vy
        self.life = self.max_life = life
        self.color, self.size, self.gravity, self.glow = color, size, gravity, glow
        self.text = text
    def update(self):
        self.vy += self.gravity
        self.x += self.vx
        self.y += self.vy
        self.life -= 1

class Particles:
    def __init__(self):
        self.list = []
    def emit(self, x, y, n, color, spread=3, life=30, size=3, gravity=0.2, glow=False):
        for _ in range(n):
            self.list.append(Particle(
                x+random.uniform(-4,4), y+random.uniform(-4,4),
                random.uniform(-spread,spread), random.uniform(-spread,spread),
                random.randint(life//2, life), color, size, gravity, glow))
    def text(self, x, y, text, color):
        self.list.append(Particle(x, y, 0, -1.5, 60, color, 0, 0.05, False, text))
    def update(self):
        for p in self.list[:]:
            p.update()
            if p.life <= 0:
                self.list.remove(p)
    def draw(self, surf, cam_x=0, cam_y=0):
        for p in self.list:
            sx, sy = int(p.x - cam_x), int(p.y - cam_y)
            if p.text:
                a = min(255, p.life * 5)
                s = font_m.render(p.text, True, p.color)
                s.set_alpha(a)
                surf.blit(s, (sx - s.get_width()//2, sy))
                continue
            a = int(255 * p.life / p.max_life)
            if p.glow:
                g = pygame.Surface((p.size*6, p.size*6), pygame.SRCALPHA)
                pygame.draw.circle(g, (*p.color, a//4), (p.size*3, p.size*3), p.size*3)
                surf.blit(g, (sx-p.size*3, sy-p.size*3))
            s = pygame.Surface((p.size*2, p.size*2), pygame.SRCALPHA)
            pygame.draw.circle(s, (*p.color, a), (p.size, p.size), p.size)
            surf.blit(s, (sx-p.size, sy-p.size))

# ============================== ДАННЫЕ ИГРЫ ==============================
class Upgrade:
    def __init__(self, id, name, desc, price, cat):
        self.id, self.name, self.desc, self.price, self.cat = id, name, desc, price, cat

UPGRADES = [
    Upgrade("sign",    "Новая вывеска",     "Больше клиентов (+15%)",        500, "stall"),
    Upgrade("lights",  "Гирлянда",          "Терпение клиентов +20%",        600, "stall"),
    Upgrade("counter", "Широкий прилавок",  "Удобнее собирать",              800, "stall"),
    Upgrade("menu",    "Меню-борд",         "Цены +20%",                     1000, "stall"),
    Upgrade("grill1",  "Гриль ур.2",        "Мясо готовится быстрее",        900, "kitchen"),
    Upgrade("grill2",  "Гриль ур.3",        "Ещё быстрее, медленнее горит",  2000, "kitchen"),
    Upgrade("fridge",  "Холодильник",       "Все цены +10%",                 1200, "kitchen"),
    Upgrade("fryer",   "Фритюрница",        "Открывает картофель фри",       700, "kitchen"),
    Upgrade("helper",  "Помощник",          "Авто-подача готового",          2500, "staff"),
    Upgrade("chef",    "Повар-напарник",    "Авто-готовка мяса",             4000, "staff"),
]

SKILLS = [
    {"id":"speed", "name":"Быстрые руки",  "desc":"+10% скорость сборки/ур",  "max":5, "cost":300},
    {"id":"tips",  "name":"Душевность",    "desc":"+15% к чаевым/ур",         "max":5, "cost":300},
    {"id":"combo", "name":"Стиль",         "desc":"Комбо дольше держится",    "max":3, "cost":500},
    {"id":"eye",   "name":"Зоркий глаз",   "desc":"+15% терпения/ур",         "max":5, "cost":400},
    {"id":"armor", "name":"Стрессоустойч.","desc":"Меньше потери репутации/ур","max":3, "cost":600},
]

def make_order(day, unlocked):
    ing = [I_LAVASH]
    if I_MEAT_B in unlocked and random.random() < 0.4:
        ing.append(I_MEAT_B)
    else:
        ing.append(I_MEAT_C)
    veg = [I_TOMATO, I_CUCUMBER, I_CABBAGE, I_ONION]
    n = random.randint(1, min(3, day))
    for v in random.sample(veg, n):
        ing.append(v)
    if I_CHEESE in unlocked and random.random() < 0.4:
        ing.append(I_CHEESE)
    if I_FRIES in unlocked and random.random() < 0.3:
        ing.append(I_FRIES)
    sauces = [I_SAUCE_G]
    if I_SAUCE_S in unlocked:
        sauces.append(I_SAUCE_S)
    n_sauce = random.randint(1, min(2, len(sauces)))
    for s in random.sample(sauces, n_sauce):
        ing.append(s)
    ing.append(I_WRAP)
    price = 180 + day * 10
    for i in ing:
        if i == I_MEAT_B: price += 60
        elif i == I_CHEESE: price += 40
        elif i == I_FRIES: price += 35
        elif i == I_SAUCE_S: price += 20
    patience = max(20, 40 - day * 1.5)
    return ing, price, patience

CUSTOMER_HINTS = ["обычный","голодный","студент","таксист","офисный","постоянный",
                   "турист","школьник","бабушка","программист","курьер","молодожён"]

# ============================== СУЩНОСТИ РЕАЛЬНОГО ВРЕМЕНИ ==============================
class CustomerRT:
    def __init__(self, seed, order_ings, price, patience, hint):
        self.seed = seed
        self.order = order_ings
        self.price = price
        self.max_patience = patience
        self.patience = patience
        self.hint = hint
        self.x = W + 60
        self.target_x = 980
        self.y = 340
        self.state = "walk_in"
        self.frame = 0
        self.mood = "normal"
        self.bubble_offset = 0

    def update(self, dt):
        self.frame += 1
        self.bubble_offset = int(math.sin(self.frame * 0.06) * 3)
        if self.state == "walk_in":
            dx = self.target_x - self.x
            if abs(dx) < 4:
                self.x = self.target_x
                self.state = "waiting"
            else:
                self.x += math.copysign(min(180 * dt, abs(dx)), dx)
        elif self.state == "waiting":
            self.patience -= dt
            if self.patience <= 0:
                self.state = "angry_leave"
                self.mood = "angry"
        elif self.state == "leaving":
            self.x += 260 * dt
            if self.x > W + 120:
                return "gone"
        elif self.state == "angry_leave":
            self.x += 400 * dt
            if self.x > W + 120:
                return "gone_angry"
        return None

    def draw(self, surf):
        draw_customer(surf, int(self.x) - 48, self.y, self.seed, self.mood, self.frame)
        if self.state == "waiting":
            self._draw_bubble(surf)

    def _draw_bubble(self, surf):
        bx = int(self.x) - 30
        by = self.y - 120 + self.bubble_offset
        bw, bh = 240, 70
        pygame.draw.rect(surf, (250, 245, 230), (bx, by, bw, bh))
        pygame.draw.rect(surf, (60, 50, 40), (bx, by, bw, bh), 2)
        pygame.draw.polygon(surf, (250, 245, 230),
            [(bx+40, by+bh), (bx+60, by+bh), (bx+50, by+bh+16)])
        pygame.draw.line(surf, (60, 50, 40), (bx+40, by+bh), (bx+50, by+bh+16), 2)
        pygame.draw.line(surf, (60, 50, 40), (bx+60, by+bh), (bx+50, by+bh+16), 2)

        ix, iy = bx + 12, by + 14
        for ing in self.order[:9]:
            draw_food(surf, ing, ix, iy, 26)
            ix += 24
            if ix > bx + bw - 30:
                ix = bx + 12
                iy += 28

        ratio = max(0, self.patience / self.max_patience)
        bar = pygame.Rect(bx+8, by+bh-8, bw-16, 4)
        pygame.draw.rect(surf, (100, 40, 40), bar)
        col = C_GREEN if ratio > 0.5 else (C_GOLD if ratio > 0.25 else C_RED)
        pygame.draw.rect(surf, col, (bar.x, bar.y, int(bar.w*ratio), bar.h))


class GrillSlot:
    def __init__(self):
        self.ing = None
        self.time = 0.0
        self.state = None

    def update(self, dt, grill_speed):
        if self.ing is None: return
        self.time += dt * grill_speed
        ct = COOK_TIME.get(self.ing, 4)
        bt = BURN_TIME.get(self.ing, 3)
        if self.time < ct:
            self.state = "raw"
        elif self.time < ct + bt:
            self.state = "cooked"
        else:
            self.state = "burned"

    def is_empty(self):
        return self.ing is None

    def place(self, ing):
        self.ing = ing
        self.time = 0.0
        self.state = "raw"

    def take(self):
        if self.ing is None: return None
        r = (self.ing, self.state)
        self.ing = None
        self.time = 0
        return r

# ============================== СОСТОЯНИЕ ==============================
class Game:
    def __init__(self):
        self.reset()

    def reset(self):
        self.day = 1
        self.money = 500
        self.reputation = 50
        self.total_earned = 0
        self.total_served = 0
        self.perfect = 0
        self.failed = 0
        self.upgrades = set()
        self.skills = {}
        self.unlocked_ings = {I_LAVASH, I_MEAT_C, I_TOMATO, I_CUCUMBER,
                               I_CABBAGE, I_ONION, I_CHEESE, I_SAUCE_G, I_WRAP}
        self.ending = None

    def skill(self, sid):
        return self.skills.get(sid, 0)

    def has_upg(self, uid):
        return uid in self.upgrades

game = Game()
SAVE_FILE = "shawarma_save.json"

def save_game():
    data = {
        "day": game.day, "money": game.money, "reputation": game.reputation,
        "total_earned": game.total_earned, "total_served": game.total_served,
        "perfect": game.perfect, "failed": game.failed,
        "upgrades": list(game.upgrades), "skills": game.skills,
        "unlocked_ings": list(game.unlocked_ings),
    }
    try:
        with open(SAVE_FILE, "w", encoding="utf-8") as f:
            json.dump(data, f)
        return True
    except:
        return False

def load_game():
    if not os.path.exists(SAVE_FILE): return False
    try:
        with open(SAVE_FILE, "r", encoding="utf-8") as f:
            data = json.load(f)
        game.day = data.get("day", 1)
        game.money = data.get("money", 500)
        game.reputation = data.get("reputation", 50)
        game.total_earned = data.get("total_earned", 0)
        game.total_served = data.get("total_served", 0)
        game.perfect = data.get("perfect", 0)
        game.failed = data.get("failed", 0)
        game.upgrades = set(data.get("upgrades", []))
        game.skills = data.get("skills", {})
        game.unlocked_ings = set(data.get("unlocked_ings", list(game.unlocked_ings)))
        return True
    except:
        return False

# ============================== ДИАЛОГИ ==============================
class Dialogue:
    def __init__(self, lines):
        self.lines = lines
        self.i = 0
    def cur(self):
        return self.lines[self.i] if self.i < len(self.lines) else None
    def next(self):
        self.i += 1
        return self.i < len(self.lines)
    def done(self):
        return self.i >= len(self.lines)

def wrap(text, font, max_w):
    out, cur = [], ""
    for w in text.split():
        t = (cur + " " + w).strip()
        if font.size(t)[0] <= max_w:
            cur = t
        else:
            if cur: out.append(cur)
            cur = w
    if cur: out.append(cur)
    return out

def draw_dialogue(d, frame):
    screen.fill(C_NIGHT)
    for y in range(H):
        k = y / H
        pygame.draw.line(screen, (int(20+k*20), int(18+k*18), int(30+k*18)), (0, y), (W, y))

    cur = d.cur()
    if not cur: return None
    speaker = cur.get("speaker")
    mood = cur.get("mood", "normal")

    if speaker == "kama":
        g = pygame.Surface((420, 420), pygame.SRCALPHA)
        pygame.draw.circle(g, (255, 200, 100, 40), (210, 210), 200)
        screen.blit(g, (40, 100))
        draw_kama(screen, 90, 130, 2.4, mood, frame, "cook")
    elif speaker == "ogly":
        g = pygame.Surface((420, 420), pygame.SRCALPHA)
        pygame.draw.circle(g, (255, 200, 100, 40), (210, 210), 200)
        screen.blit(g, (40, 100))
        draw_ogly(screen, 90, 110, 2.4, mood, frame, "cook")
    elif speaker == "customer":
        seed = cur.get("seed", 42)
        draw_customer(screen, 130, 160, seed, mood, frame)

    panel = pygame.Rect(400, H-280, W-440, 240)
    pygame.draw.rect(screen, (0,0,0,120), panel.move(6, 6))
    pygame.draw.rect(screen, C_PANEL, panel)
    pygame.draw.rect(screen, C_GOLD, panel, 3)

    names = {"kama":"Камаладдин", "ogly":"Оглы", "customer":"Покупатель",
             "narrator":"", "both":"Камаладдин и Оглы", None:""}
    name = names.get(speaker, "")
    if name:
        name_rect = pygame.Rect(panel.x+20, panel.y-34, font_m.size(name)[0]+40, 32)
        pygame.draw.rect(screen, C_GOLD_D, name_rect)
        pygame.draw.rect(screen, C_GOLD, name_rect, 2)
        ns = font_m.render(name, True, C_TEXT)
        screen.blit(ns, (name_rect.x+20, name_rect.centery - ns.get_height()//2))

    text = cur.get("text", "")
    lines = wrap(text, font_l, panel.w - 60)
    y = panel.y + 30
    for ln in lines[:5]:
        ts = font_l.render(ln, True, (20,20,30))
        screen.blit(ts, (panel.x+32, y+2))
        s = font_l.render(ln, True, C_TEXT)
        screen.blit(s, (panel.x+30, y))
        y += 32

    btn = pygame.Rect(panel.right-220, panel.bottom-56, 200, 42)
    pygame.draw.rect(screen, C_PANEL_D, btn)
    pygame.draw.rect(screen, C_GOLD, btn, 2)
    hint = "Продолжить >>" if not d.done() else "Готово"
    hs = font_m.render(hint, True, C_TEXT)
    screen.blit(hs, (btn.centerx - hs.get_width()//2, btn.centery - hs.get_height()//2))

    ps = font_s.render(f"{d.i+1}/{len(d.lines)}   SPACE — далее", True, C_TEXT_DIM)
    screen.blit(ps, (panel.x+20, panel.bottom-30))

    return btn

def run_dialogue(d):
    frame = 0
    while not d.done():
        clock.tick(60)
        frame += 1
        draw_dialogue(d, frame)
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                pygame.quit(); sys.exit()
            if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
                pygame.quit(); sys.exit()
            if (e.type == pygame.KEYDOWN and e.key == pygame.K_SPACE) or \
               (e.type == pygame.MOUSEBUTTONDOWN and e.button == 1):
                d.next()
        pygame.display.flip()

# ============================== СЦЕНАРИЙ ==============================
def script_intro():
    return Dialogue([
        {"speaker":"narrator","text":"Рассвет. Город N. Неоновая вывеска «ШАУРМА №1» мигает и жужжит."},
        {"speaker":"ogly","mood":"normal","text":"Камаладдин, сынок! Подъём! Открываемся в семь, а ты дрыхнешь!"},
        {"speaker":"kama","mood":"sad","text":"Дядя Оглы, ну пять минут... Я всю ночь изучал рецептуру нового маринада."},
        {"speaker":"ogly","mood":"normal","text":"Маринад? У нас один маринад — соль, перец и уважение к клиенту."},
        {"speaker":"kama","mood":"happy","text":"Дядя, я хочу открыть свою сеть. Настоящую. С брендом, с логотипом..."},
        {"speaker":"ogly","mood":"normal","text":"Мечтатель. Сначала научись не жечь лаваш. Вчера три штуки в мусор ушли."},
        {"speaker":"kama","mood":"normal","text":"Это было один раз!"},
        {"speaker":"ogly","mood":"happy","text":"Пять, сынок. Я считал. Ладно. Надевай фартук — клиенты идут."},
        {"speaker":"narrator","text":"Ты выходишь за прилавок. Сегодня — твой первый настоящий день."},
        {"speaker":"narrator","text":"ЦЕЛЬ: 7 дней, репутация >=60, деньги >=1500 — хороший финал."},
    ])

MORNING_SCRIPTS = {
    1: [
        {"speaker":"ogly","mood":"normal","text":"Слушай сюда. Клиент называет заказ — ты собираешь."},
        {"speaker":"ogly","mood":"normal","text":"Порядок: лаваш, мясо, овощи, соус, завернуть."},
        {"speaker":"ogly","mood":"normal","text":"Мясо идёт сначала на гриль. Следи, чтобы не подгорело."},
        {"speaker":"narrator","text":"СОВЕТ: кликай ингредиенты внизу. Мясо — в гриль справа. Не зевай."},
    ],
    2: [
        {"speaker":"kama","mood":"happy","text":"Дядя, вчера получилось! Три идеальные шаурмы!"},
        {"speaker":"ogly","mood":"happy","text":"Молодец. Сегодня пятница — людей будет больше."},
        {"speaker":"ogly","mood":"normal","text":"И добавил говядину. Она дороже, но клиенты любят."},
    ],
    3: [
        {"speaker":"kama","mood":"normal","text":"Дядя, а почему ты не расширяешься?"},
        {"speaker":"ogly","mood":"sad","text":"Был второй ларёк. Сгорел. Газовый баллон, ночь, всё."},
        {"speaker":"kama","mood":"surprised","text":"Ого..."},
        {"speaker":"ogly","mood":"normal","text":"Вот поэтому у нас всё простое и надёжное."},
    ],
    4: [
        {"speaker":"ogly","mood":"sad","text":"Через дорогу открывается «Шаурма Хаус». Сеть."},
        {"speaker":"kama","mood":"surprised","text":"Конкуренты?"},
        {"speaker":"ogly","mood":"angry","text":"Конкуренты. Цены у них на двадцать рублей ниже."},
        {"speaker":"kama","mood":"normal","text":"У нас качество и репутация."},
    ],
    5: [
        {"speaker":"kama","mood":"happy","text":"Дядя, идея! «Шаурма дня» — со скидкой, но с сыром."},
        {"speaker":"ogly","mood":"happy","text":"Хм. Ладно, чертёнок. Открывай фритюрницу."},
    ],
    6: [
        {"speaker":"narrator","text":"Дождь. Улица пустая. Оглы мрачно смотрит на выручку."},
        {"speaker":"ogly","mood":"sad","text":"Плохой день. В такую погоду никто не идёт."},
        {"speaker":"kama","mood":"happy","text":"А давай доставку? Я разнесу по офисам."},
        {"speaker":"ogly","mood":"happy","text":"Мечтатель. Ладно, если выстоим — придумаем."},
    ],
    7: [
        {"speaker":"narrator","text":"Последний день. Судьба ларька решится сегодня."},
        {"speaker":"ogly","mood":"normal","text":"Камаладдин. Год назад я взял тебя посудомойщиком."},
        {"speaker":"kama","mood":"normal","text":"А теперь я делаю шаурму быстрее тебя, дядя."},
        {"speaker":"ogly","mood":"happy","text":"Быстрее? Спортивный интерес. Покажи всё, чему научился."},
    ],
}

EVENING_SCRIPTS = {
    1: [
        {"speaker":"ogly","mood":"normal","text":"Первый день. Как ощущения?"},
        {"speaker":"kama","mood":"normal","text":"Тяжело. Но интересно."},
        {"speaker":"ogly","mood":"happy","text":"Это нормально. К вечеру руки привыкнут."},
    ],
    2: [
        {"speaker":"ogly","mood":"happy","text":"С говядиной разобрался! Хвалю."},
        {"speaker":"kama","mood":"happy","text":"Она дороже, но клиенты довольные уходят."},
    ],
    3: [
        {"speaker":"ogly","mood":"sad","text":"Я сегодня вспомнил тот ларёк. Который сгорел."},
        {"speaker":"kama","mood":"normal","text":"Дядя, ты его отстроил заново. Здесь."},
        {"speaker":"ogly","mood":"normal","text":"Отстроил. Но страх остался."},
    ],
    4: [
        {"speaker":"ogly","mood":"angry","text":"Видел их вывеску? Срам какой-то."},
        {"speaker":"kama","mood":"normal","text":"Зато у нас — с душой."},
        {"speaker":"ogly","mood":"happy","text":"Философ. Но прав. Сегодня не проиграли."},
    ],
    5: [
        {"speaker":"kama","mood":"happy","text":"Дядя! «Шаурма дня» улетела за час!"},
        {"speaker":"ogly","mood":"happy","text":"Признаю, идея годная. Кто бы мог подумать."},
    ],
    6: [
        {"speaker":"ogly","mood":"normal","text":"Доставку завтра сделаем. Я подумал — идея годная."},
        {"speaker":"kama","mood":"happy","text":"Правда?!"},
        {"speaker":"ogly","mood":"happy","text":"Правда. Но сначала — приложение и логотип."},
    ],
    7: [
        {"speaker":"narrator","text":"Конец седьмого дня. Оглы вытирает руки о фартук."},
    ],
}

def ending_good():
    return Dialogue([
        {"speaker":"ogly","mood":"happy","text":"Камаладдин. Я 27 лет стою за этим прилавком. И знаешь что?"},
        {"speaker":"kama","mood":"normal","text":"Что, дядя?"},
        {"speaker":"ogly","mood":"happy","text":"Ты — лучший, кого я видел. И я не про мясо. Я про голову."},
        {"speaker":"ogly","mood":"normal","text":"Помнишь, ты говорил про сеть? Я подумал. Надо делать."},
        {"speaker":"kama","mood":"surprised","text":"Серьёзно?!"},
        {"speaker":"ogly","mood":"happy","text":"Серьёзно. Первый ларёк — здесь. Второй — твой."},
        {"speaker":"kama","mood":"happy","text":"Я готов, дядя. Я готов!"},
        {"speaker":"ogly","mood":"happy","text":"Название придумал?"},
        {"speaker":"kama","mood":"happy","text":"«Камаладдин и Оглы». Чтобы все знали."},
        {"speaker":"narrator","text":">>> ХОРОШИЙ ФИНАЛ. Сеть основана."},
    ])

def ending_neutral():
    return Dialogue([
        {"speaker":"ogly","mood":"normal","text":"Ну что, Камаладдин. Выстояли."},
        {"speaker":"kama","mood":"normal","text":"Выстояли. Но могли лучше."},
        {"speaker":"ogly","mood":"normal","text":"Могли. Но и так неплохо."},
        {"speaker":"ogly","mood":"happy","text":"Через год — поговорим о расширении."},
        {"speaker":"narrator","text":">>> НЕЙТРАЛЬНЫЙ ФИНАЛ."},
    ])

def ending_bad():
    return Dialogue([
        {"speaker":"narrator","text":"Молчание. Пустая касса. За окном — конкурент."},
        {"speaker":"ogly","mood":"sad","text":"Не тот месяц. Не та неделя. Не тот ты."},
        {"speaker":"kama","mood":"sad","text":"Дядя, я старался..."},
        {"speaker":"ogly","mood":"sad","text":"Бизнес — не про «старался». Бизнес — про результат."},
        {"speaker":"narrator","text":">>> ПЛОХОЙ ФИНАЛ. Ты можешь попробовать снова."},
    ])

# ============================== МЕНЮ ==============================
class FloatingIng:
    def __init__(self):
        self.reset()
        self.y = random.randint(-400, H)
    def reset(self):
        self.x = random.randint(0, W)
        self.y = -random.randint(40, 400)
        self.ing = random.choice(list(ING_NAME.keys()))
        self.size = random.randint(38, 58)
        self.rot = random.uniform(-15, 15)
        self.spin = random.uniform(-0.3, 0.3)
        self.vy = random.uniform(0.4, 1.2)
        self.vx = random.uniform(-0.3, 0.3)

def draw_menu_bg(frame):
    for y in range(H):
        k = y / H
        pygame.draw.line(screen, (int(12+k*20), int(10+k*16), int(28+k*22)), (0, y), (W, y))

    rng = random.Random(123)
    for i in range(60):
        sx = rng.randint(0, W)
        sy = rng.randint(0, 240)
        tw = (math.sin(frame*0.05 + i) * 0.5 + 0.5)
        c = int(140 + tw * 115)
        pygame.draw.circle(screen, (c,c,c), (sx, sy), 1)

    rng2 = random.Random(777)
    x = -20
    while x < W + 40:
        bw = rng2.randint(60, 120)
        bh = rng2.randint(60, 180)
        pygame.draw.rect(screen, (30, 25, 50), (x, 380 - bh, bw, bh))
        for wy in range(390 - bh, 370, 20):
            for wx in range(x+10, x+bw-10, 18):
                lit = rng2.random() < 0.35
                c = (245, 200, 100) if lit else (40, 35, 60)
                pygame.draw.rect(screen, c, (wx, wy, 8, 12))
        x += bw + 8

    pygame.draw.rect(screen, (30, 28, 38), (0, 380, W, H-380))
    for i in range(0, W, 40):
        pygame.draw.line(screen, (45, 42, 55), (i, 380), (i-30, H), 1)

    stall_y = 400
    pygame.draw.rect(screen, (55, 35, 25), (60, stall_y, 320, 200))
    pygame.draw.rect(screen, (80, 50, 35), (60, stall_y, 320, 20))
    pygame.draw.rect(screen, (200, 50, 50), (80, stall_y-50, 280, 40))
    pygame.draw.rect(screen, (245, 200, 80), (80, stall_y-50, 280, 40), 3)
    lit = (frame // 30) % 2 == 0
    lbl = font_l.render("ШАУРМА №1", True, (250, 240, 200) if lit else (150, 140, 100))
    screen.blit(lbl, (220 - lbl.get_width()//2, stall_y - 40))

def draw_main_menu(floats, frame):
    draw_menu_bg(frame)

    for f in floats:
        if f.y > H + 60:
            f.reset()
        f.y += f.vy
        f.x += f.vx
        f.rot += f.spin

    for f in floats:
        surf = pygame.Surface((f.size + 8, f.size + 8), pygame.SRCALPHA)
        draw_food(surf, f.ing, 4, 4, f.size)
        surf.set_alpha(140)
        rotated = pygame.transform.rotate(surf, f.rot)
        rect = rotated.get_rect(center=(f.x, f.y))
        screen.blit(rotated, rect)

    overlay = pygame.Surface((W, H), pygame.SRCALPHA)
    pygame.draw.rect(overlay, (10, 8, 18, 140), (0, 0, W, H))
    screen.blit(overlay, (0, 0))

    title_shadow = font_xxl.render("ШАУРМИСТ", True, (10, 8, 20))
    title = font_xxl.render("ШАУРМИСТ", True, C_GOLD)
    tx = W//2 - title.get_width()//2
    ty = 80 + int(math.sin(frame*0.03) * 4)
    screen.blit(title_shadow, (tx+4, ty+4))
    screen.blit(title, (tx, ty))

    subtitle = font_l.render("Камаладдин и Оглы", True, C_TEXT)
    screen.blit(subtitle, (W//2 - subtitle.get_width()//2, ty + title.get_height() - 6))

    draw_kama(screen, 180, 300, 1.6, "happy", frame, "walk")
    draw_ogly(screen, 950, 280, 1.6, "happy", frame, "cook")

    buttons = [
        ("НОВАЯ ИГРА", "new"),
        ("ПРОДОЛЖИТЬ", "continue"),
        ("ОБ ИГРЕ", "about"),
        ("ВЫХОД", "exit"),
    ]
    rects = []
    bx = W//2 - 160
    by = 320
    for text, key in buttons:
        r = pygame.Rect(bx, by, 320, 52)
        rects.append((r, key, text))
        by += 62

    mx, my = pygame.mouse.get_pos()
    for r, key, text in rects:
        hover = r.collidepoint(mx, my)
        pygame.draw.rect(screen, (10,10,20), r.move(4, 4))
        bg_col = (80, 60, 100) if hover else C_PANEL
        if key == "continue" and not os.path.exists(SAVE_FILE):
            bg_col = (40, 40, 45)
        pygame.draw.rect(screen, bg_col, r)
        pygame.draw.rect(screen, C_GOLD if hover else C_GOLD_D, r, 3 if hover else 2)
        tc = C_TEXT
        if key == "continue" and not os.path.exists(SAVE_FILE):
            tc = C_TEXT_DIM
        s = font_l.render(text, True, tc)
        screen.blit(s, (r.centerx - s.get_width()//2, r.centery - s.get_height()//2))

    info = font_s.render("v1.1   © 2025   Made with pygame", True, C_TEXT_DIM)
    screen.blit(info, (W//2 - info.get_width()//2, H-30))

    return rects

def about_screen():
    frame = 0
    while True:
        clock.tick(60)
        frame += 1
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                pygame.quit(); sys.exit()
            if e.type == pygame.KEYDOWN or e.type == pygame.MOUSEBUTTONDOWN:
                return
        screen.fill(C_NIGHT)
        for y in range(H):
            k = y/H
            pygame.draw.line(screen, (int(20+k*20), int(18+k*16), int(30+k*22)), (0,y), (W,y))

        title = font_xl.render("ОБ ИГРЕ", True, C_GOLD)
        screen.blit(title, (W//2 - title.get_width()//2, 40))

        lines = [
            "СИМУЛЯТОР ШАУРМИСТА — история двух друзей.",
            "",
            "Камаладдин — молодой, амбициозный, мечтает о сети.",
            "Оглы — его старший друг, владелец ларька.",
            "",
            "УПРАВЛЕНИЕ:",
            "  МЫШЬ — выбирать ингредиенты и кнопки",
            "  SPACE — диалоги / отказать клиенту",
            "  ESC — закрыть меню",
            "",
            "МЕХАНИКА:",
            "  • Клиенты приходят в реальном времени",
            "  • Собирай: лаваш → мясо → овощи → соус → завернуть",
            "  • Мясо готовится на гриле — не дай подгореть!",
            "  • Апгрейды ларька и навыки открывают новое",
            "",
            "ЦЕЛЬ: 7 дней, репутация >=60, деньги >=1500.",
            "",
            "SPACE / клик — назад",
        ]
        y = 130
        for line in lines:
            s = font_m.render(line, True, C_TEXT if not line.startswith(" ") else C_TEXT_DIM)
            screen.blit(s, (W//2 - s.get_width()//2, y))
            y += 26
        pygame.display.flip()

# ============================== МАГАЗИН ==============================
def shop_screen():
    frame = 0
    scroll = 0
    mx, my = 0, 0
    while True:
        clock.tick(60)
        frame += 1
        mx, my = pygame.mouse.get_pos()
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                pygame.quit(); sys.exit()
            if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
                return
            if e.type == pygame.MOUSEBUTTONDOWN:
                if e.button == 4:
                    scroll = min(0, scroll + 20)
                if e.button == 5:
                    scroll -= 20
                if e.button == 1:
                    for i, up in enumerate(UPGRADES):
                        y = 130 + i*90 + scroll
                        r = pygame.Rect(60, y, W-200, 80)
                        if r.collidepoint(mx, my):
                            if up.id not in game.upgrades and game.money >= up.price:
                                game.money -= up.price
                                game.upgrades.add(up.id)
                                if up.id == "fryer":
                                    game.unlocked_ings.add(I_FRIES)

        screen.fill(C_BG)
        pygame.draw.rect(screen, C_PANEL, (0, 0, W, 100))
        t = font_xl.render("МАГАЗИН ЛАРЬКА", True, C_GOLD)
        screen.blit(t, (W//2 - t.get_width()//2, 20))
        m = font_l.render(f"{game.money}₽", True, C_GREEN)
        screen.blit(m, (W - m.get_width() - 30, 40))

        cats = {"stall": "ЛАРЁК", "kitchen": "КУХНЯ", "staff": "ПЕРСОНАЛ"}
        cat_col = {"stall": C_GOLD, "kitchen": C_ORANGE, "staff": C_PURPLE}
        cur_cat = None
        for i, up in enumerate(UPGRADES):
            y = 130 + i*90 + scroll
            if y < -100 or y > H:
                continue
            if up.cat != cur_cat:
                cur_cat = up.cat
                label = font_m.render(cats.get(up.cat, "?"), True, cat_col[up.cat])
                screen.blit(label, (60, y - 24))

            r = pygame.Rect(60, y, W-200, 80)
            hover = r.collidepoint(mx, my)
            bought = up.id in game.upgrades
            can = game.money >= up.price and not bought
            bg = (55, 85, 55) if bought else ((70, 60, 100) if can and hover else C_PANEL_D)
            pygame.draw.rect(screen, bg, r)
            border = C_GREEN_D if bought else (C_GOLD if can else C_TEXT_DIM)
            pygame.draw.rect(screen, border, r, 2)

            ns = font_m.render(up.name, True, C_TEXT)
            screen.blit(ns, (r.x+20, r.y+8))
            ds = font_s.render(up.desc, True, C_TEXT_DIM)
            screen.blit(ds, (r.x+20, r.y+36))
            pr_txt = "КУПЛЕНО" if bought else f"{up.price}₽"
            pr_col = C_GREEN if bought or can else C_RED
            ps = font_m.render(pr_txt, True, pr_col)
            screen.blit(ps, (r.right - ps.get_width() - 20, r.centery - ps.get_height()//2))

        hint = font_s.render("ESC — закрыть", True, C_TEXT_DIM)
        screen.blit(hint, (30, H-30))
        pygame.display.flip()

# ============================== НАВЫКИ ==============================
def skills_screen():
    frame = 0
    mx, my = 0, 0
    while True:
        clock.tick(60)
        frame += 1
        mx, my = pygame.mouse.get_pos()
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                pygame.quit(); sys.exit()
            if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
                return
            if e.type == pygame.MOUSEBUTTONDOWN and e.button == 1:
                for i, sk in enumerate(SKILLS):
                    r = pygame.Rect(60, 130 + i*90, W-120, 80)
                    if r.collidepoint(mx, my):
                        lvl = game.skill(sk["id"])
                        cost = sk["cost"] * (lvl + 1)
                        if lvl < sk["max"] and game.money >= cost:
                            game.money -= cost
                            game.skills[sk["id"]] = lvl + 1

        screen.fill(C_BG)
        pygame.draw.rect(screen, C_PANEL, (0, 0, W, 100))
        t = font_xl.render("НАВЫКИ КАМАЛАДДИНА", True, C_PURPLE)
        screen.blit(t, (W//2 - t.get_width()//2, 20))
        m = font_l.render(f"{game.money}₽", True, C_GREEN)
        screen.blit(m, (W - m.get_width() - 30, 40))

        for i, sk in enumerate(SKILLS):
            r = pygame.Rect(60, 130 + i*90, W-120, 80)
            lvl = game.skill(sk["id"])
            maxed = lvl >= sk["max"]
            cost = sk["cost"] * (lvl + 1)
            can = not maxed and game.money >= cost
            hover = r.collidepoint(mx, my)
            bg = (70, 55, 90) if hover and can else C_PANEL_D
            pygame.draw.rect(screen, bg, r)
            border = C_PURPLE if can else C_TEXT_DIM
            if maxed:
                border = C_GREEN_D
            pygame.draw.rect(screen, border, r, 2)

            ns = font_m.render(sk["name"], True, C_TEXT)
            screen.blit(ns, (r.x+20, r.y+8))
            ds = font_s.render(sk["desc"], True, C_TEXT_DIM)
            screen.blit(ds, (r.x+20, r.y+38))

            for j in range(sk["max"]):
                rx = r.x + 500 + j*24
                ry = r.centery - 10
                filled = j < lvl
                pygame.draw.rect(screen, C_GREEN if filled else C_PANEL, (rx, ry, 18, 18))
                pygame.draw.rect(screen, C_TEXT_DIM, (rx, ry, 18, 18), 2)

            if maxed:
                pr = "МАКС"
                col = C_GREEN_D
            else:
                pr = f"{cost}₽"
                col = C_GREEN if can else C_RED
            ps = font_m.render(pr, True, col)
            screen.blit(ps, (r.right - ps.get_width() - 20, r.centery - ps.get_height()//2))

        hint = font_s.render("ESC — закрыть", True, C_TEXT_DIM)
        screen.blit(hint, (30, H-30))
        pygame.display.flip()

# ============================== ИТОГ ДНЯ ==============================
def day_summary(day, earned, served, perfect, failed):
    btn = pygame.Rect(W//2-180, H-110, 360, 60)
    frame = 0
    while True:
        clock.tick(60)
        frame += 1
        mx, my = pygame.mouse.get_pos()
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                pygame.quit(); sys.exit()
            if e.type == pygame.KEYDOWN and e.key == pygame.K_SPACE:
                return
            if e.type == pygame.MOUSEBUTTONDOWN and e.button == 1 and btn.collidepoint(mx, my):
                return
        screen.fill(C_NIGHT)
        for y in range(H):
            k = y/H
            pygame.draw.line(screen, (int(20+k*22), int(18+k*20), int(30+k*26)), (0,y), (W,y))

        t = font_xxl.render(f"КОНЕЦ ДНЯ {day}", True, C_GOLD)
        screen.blit(t, (W//2 - t.get_width()//2, 60))

        panel = pygame.Rect(W//2-400, 200, 800, 380)
        pygame.draw.rect(screen, C_PANEL, panel)
        pygame.draw.rect(screen, C_GOLD, panel, 3)

        rows = [
            ("Обслужено клиентов", f"{served}", C_TEXT),
            ("Идеальных заказов", f"{perfect}", C_GREEN),
            ("Провалено", f"{failed}", C_RED),
            ("Заработано за день", f"{earned}₽", C_GOLD),
            ("Всего в кассе", f"{game.money}₽", C_GREEN),
            ("Репутация", f"{game.reputation}", C_BLUE),
        ]
        y = panel.y + 30
        for label, value, col in rows:
            ls = font_l.render(label, True, C_TEXT_DIM)
            screen.blit(ls, (panel.x+40, y))
            vs = font_l.render(value, True, col)
            screen.blit(vs, (panel.right - vs.get_width() - 40, y))
            y += 52

        hover = btn.collidepoint(mx, my)
        pygame.draw.rect(screen, (90,70,120) if hover else C_PANEL, btn)
        pygame.draw.rect(screen, C_GOLD, btn, 3)
        bs = font_l.render("ПРОДОЛЖИТЬ >>", True, C_TEXT)
        screen.blit(bs, (btn.centerx - bs.get_width()//2, btn.centery - bs.get_height()//2))
        pygame.display.flip()

# ============================== ГЕЙМПЛЕЙ ДНЯ ==============================
def play_day(day):
    particles = Particles()

    base_goal = 6 + day
    total_customers = base_goal + random.randint(-1, 2)
    if game.has_upg("sign"):
        total_customers = int(total_customers * 1.15)

    patience_mult = 1.0
    if game.has_upg("lights"):
        patience_mult += 0.2
    patience_mult += game.skill("eye") * 0.15

    base_interval = max(3.0, 7.0 - day * 0.4)
    if game.has_upg("sign"):
        base_interval *= 0.85

    price_mult = 1.0
    if game.has_upg("menu"):
        price_mult += 0.2
    if game.has_upg("fridge"):
        price_mult += 0.1
    price_mult += game.skill("tips") * 0.05

    grill_speed = 1.0
    if game.has_upg("grill1"):
        grill_speed += 0.3
    if game.has_upg("grill2"):
        grill_speed += 0.3

    scene = pygame.Surface((W, H))

    customers = []
    next_customer_in = 1.5
    queue_served = 0
    queue_failed = 0
    queue_perfect = 0
    earned = 0

    current_order_ings = []
    grill_slots = [GrillSlot() for _ in range(3)]

    all_ings = [I_LAVASH, I_MEAT_C, I_MEAT_B, I_TOMATO, I_CUCUMBER,
                I_CABBAGE, I_ONION, I_CHEESE, I_FRIES,
                I_SAUCE_G, I_SAUCE_S, I_WRAP]
    ing_available = [i for i in all_ings if i in game.unlocked_ings]
    ing_available = list(dict.fromkeys(ing_available))

    ING_SIZE = 76
    ING_GAP = 8
    ING_Y = H - 100
    ing_rects = []
    for i, ing in enumerate(ing_available):
        x = 20 + i * (ING_SIZE + ING_GAP)
        r = pygame.Rect(x, ING_Y, ING_SIZE, ING_SIZE)
        ing_rects.append((r, ing))

    GRILL_RECTS = []
    grill_x = W - 240
    grill_y = 100
    for i in range(3):
        r = pygame.Rect(grill_x, grill_y + i*110, 200, 100)
        GRILL_RECTS.append(r)

    msg = ""
    msg_t = 0
    msg_col = C_TEXT

    last_t = pygame.time.get_ticks()
    frame = 0

    day_ending = False
    end_t = 0.0

    while not day_ending:
        now = pygame.time.get_ticks()
        dt = min(0.05, (now - last_t) / 1000.0)
        last_t = now
        frame += 1
        clock.tick(60)

        next_customer_in -= dt
        if next_customer_in <= 0 and len(customers) < 4:
            next_customer_in = base_interval * random.uniform(0.7, 1.4)
            seed = random.randint(0, 10**6)
            order_ings, base_price, base_pat = make_order(day, game.unlocked_ings)
            final_price = int(base_price * price_mult)
            final_pat = base_pat * patience_mult
            hint = random.choice(CUSTOMER_HINTS)
            customers.append(CustomerRT(seed, order_ings, final_price, final_pat, hint))

        for c in customers[:]:
            res = c.update(dt)
            if res == "gone":
                customers.remove(c)
            elif res == "gone_angry":
                customers.remove(c)
                queue_failed += 1
                game.reputation = max(0, game.reputation - 3 + game.skill("armor"))
                msg = "Клиент ушёл! Репутация -3"
                msg_col = C_RED
                msg_t = 120
                particles.emit(c.x, c.y+30, 12, (200,60,60), 4, 30, 3)

        for g in grill_slots:
            g.update(dt, grill_speed)
            if game.has_upg("chef") and g.is_empty():
                for c in customers:
                    if c.state != "waiting":
                        continue
                    if I_MEAT_C in c.order or I_MEAT_B in c.order:
                        meat = I_MEAT_B if I_MEAT_B in c.order else I_MEAT_C
                        g.place(meat)
                        break

        mx, my = pygame.mouse.get_pos()
        left_click = False
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                pygame.quit(); sys.exit()
            if e.type == pygame.KEYDOWN:
                if e.key == pygame.K_ESCAPE:
                    pygame.quit(); sys.exit()
                if e.key == pygame.K_SPACE:
                    waiting = [c for c in customers if c.state == "waiting"]
                    if waiting:
                        c = waiting[0]
                        customers.remove(c)
                        queue_failed += 1
                        game.reputation = max(0, game.reputation - 2 + game.skill("armor"))
                        msg = "Отказал клиенту. Репутация -2"
                        msg_col = C_RED
                        msg_t = 120
            if e.type == pygame.MOUSEBUTTONDOWN and e.button == 1:
                left_click = True

        if left_click:
            for r, ing in ing_rects:
                if r.collidepoint(mx, my):
                    waiting = [c for c in customers if c.state == "waiting"]
                    if not waiting:
                        msg = "Нет клиента — некому отдать"
                        msg_col = C_TEXT_DIM
                        msg_t = 90
                        break
                    c = waiting[0]
                    expected_pos = len(current_order_ings)
                    if expected_pos >= len(c.order):
                        msg = "Заказ собран, отдай!"
                        msg_col = C_TEXT_DIM
                        msg_t = 90
                        break
                    expected = c.order[expected_pos]

                    if ing in GRILL_INGS:
                        if expected != ing:
                            msg = f"Сейчас нужно: {ING_SHORT[expected]}"
                            msg_col = C_RED
                            msg_t = 90
                            break
                        placed = False
                        for gi, g in enumerate(grill_slots):
                            if g.is_empty():
                                g.place(ing)
                                placed = True
                                particles.emit(r.centerx, r.centery, 6, (240,200,120), 2, 20)
                                break
                        if not placed:
                            msg = "Гриль занят!"
                            msg_col = C_RED
                            msg_t = 90
                        break

                    if ing == expected:
                        current_order_ings.append(ing)
                        particles.emit(r.centerx, r.centery, 5, (240,240,200), 2, 20)
                        if ing == I_WRAP:
                            c.state = "leaving"
                            c.mood = "happy"
                            ratio = c.patience / c.max_patience
                            quality = "perfect" if ratio > 0.4 else "good"
                            if quality == "perfect":
                                earn = int(c.price * 1.35)
                                queue_perfect += 1
                                game.reputation = min(100, game.reputation + 3)
                                particles.text(c.x, c.y-60, "PERFECT!", C_GOLD)
                                msg = f"PERFECT! +{earn}₽"
                                msg_col = C_GOLD
                                game.perfect += 1
                            else:
                                earn = int(c.price * 1.1)
                                game.reputation = min(100, game.reputation + 2)
                                particles.text(c.x, c.y-60, "ХОРОШО", C_GREEN)
                                msg = f"+{earn}₽"
                                msg_col = C_GREEN
                            msg_t = 120
                            earned += earn
                            queue_served += 1
                            game.total_served += 1
                            current_order_ings = []
                            particles.emit(c.x, c.y, 15, C_GOLD, 4, 30, 3, glow=True)
                        break
                    else:
                        msg = f"Не то. Нужно: {ING_SHORT[expected]}"
                        msg_col = C_RED
                        msg_t = 90
                        break

            for gi, r in enumerate(GRILL_RECTS):
                if r.collidepoint(mx, my):
                    g = grill_slots[gi]
                    if g.is_empty():
                        break
                    if g.state == "burned":
                        g.take()
                        msg = "Сгорело! Выкинул."
                        msg_col = C_RED
                        msg_t = 90
                        particles.emit(r.centerx, r.centery, 8, (60,40,30), 3, 25)
                        break
                    if g.state == "raw":
                        msg = "Ещё сырое!"
                        msg_col = C_GOLD
                        msg_t = 90
                        break
                    waiting = [c for c in customers if c.state == "waiting"]
                    if not waiting:
                        msg = "Некому отдать"
                        msg_col = C_TEXT_DIM
                        msg_t = 90
                        break
                    c = waiting[0]
                    expected_pos = len(current_order_ings)
                    if expected_pos >= len(c.order):
                        break
                    expected = c.order[expected_pos]
                    if expected == g.ing:
                        current_order_ings.append(g.ing)
                        g.take()
                        particles.emit(r.centerx, r.centery, 8, (240,200,120), 3, 25, 2, 0.1)
                    else:
                        msg = f"Нужно: {ING_SHORT[expected]}"
                        msg_col = C_RED
                        msg_t = 90
                    break

        # ============ РЕНДЕР ============
        scene.fill((0,0,0))

        for y in range(340):
            k = y/340
            r = int(60 * (1-k) + 200 * k)
            g = int(90 * (1-k) + 160 * k)
            b = int(140 * (1-k) + 120 * k)
            pygame.draw.line(scene, (r,g,b), (0, y), (W, y))

        rng = random.Random(555)
        bx = 0
        while bx < W:
            bw = rng.randint(60, 130)
            bh = rng.randint(90, 180)
            pygame.draw.rect(scene, (55, 45, 70), (bx, 340-bh, bw, bh))
            for wy in range(360 - bh, 330, 22):
                for wx in range(bx+10, bx+bw-10, 20):
                    c = (240, 200, 120) if rng.random() < 0.3 else (40, 35, 55)
                    pygame.draw.rect(scene, c, (wx, wy, 10, 14))
            bx += bw + 6

        pygame.draw.rect(scene, (40, 38, 48), (0, 340, W, 120))
        for i in range(0, W, 50):
            pygame.draw.line(scene, (55, 50, 65), (i, 340), (i, 460), 1)

        stall_x = W//2 - 300
        stall_y = 240
        stall_w = 600
        stall_h = 240

        pygame.draw.rect(scene, (20, 18, 30), (stall_x-8, stall_y+8, stall_w+16, stall_h))
        pygame.draw.rect(scene, (85, 55, 40), (stall_x, stall_y, stall_w, stall_h))
        pygame.draw.rect(scene, (60, 40, 30), (stall_x, stall_y, stall_w, 20))

        pygame.draw.polygon(scene, (130, 45, 45), [
            (stall_x-20, stall_y+10),
            (stall_x + stall_w + 20, stall_y+10),
            (stall_x + stall_w - 10, stall_y - 30),
            (stall_x + 10, stall_y - 30)])
        pygame.draw.polygon(scene, (80, 25, 25), [
            (stall_x-20, stall_y+10),
            (stall_x + stall_w + 20, stall_y+10),
            (stall_x + stall_w - 10, stall_y - 30),
            (stall_x + 10, stall_y - 30)], 3)

        sign_rect = pygame.Rect(stall_x + 140, stall_y - 80, 320, 60)
        pygame.draw.rect(scene, (200, 50, 50), sign_rect)
        pygame.draw.rect(scene, (245, 200, 80), sign_rect, 4)
        lit = (frame // 20) % 2 == 0
        sign_text = font_l.render("ШАУРМА", True, (250, 240, 200) if lit else (150, 140, 100))
        scene.blit(sign_text, (sign_rect.centerx - sign_text.get_width()//2,
                                sign_rect.centery - sign_text.get_height()//2))

        counter = pygame.Rect(stall_x + 20, stall_y + 130, stall_w - 40, 40)
        pygame.draw.rect(scene, (130, 90, 60), counter)
        pygame.draw.rect(scene, (90, 60, 40), counter, 3)

        menu_board = pygame.Rect(stall_x + 60, stall_y + 30, 200, 100)
        pygame.draw.rect(scene, (30, 25, 40), menu_board)
        pygame.draw.rect(scene, (200, 180, 120), menu_board, 2)
        mb_text = font_s.render("МЕНЮ", True, (240, 220, 160))
        scene.blit(mb_text, (menu_board.centerx - mb_text.get_width()//2, menu_board.y + 6))
        for i, item in enumerate(["Шаурма", "С сыром", "С фри", "Острая"]):
            it = font_xs.render(f"- {item}", True, (220, 210, 180))
            scene.blit(it, (menu_board.x + 10, menu_board.y + 30 + i*16))

        draw_kama(scene, stall_x + 280, stall_y + 20, 1.6, "normal", frame, "cook")

        grill_panel = pygame.Rect(stall_x + 320, stall_y + 60, 240, 100)
        pygame.draw.rect(scene, (40, 40, 45), grill_panel)
        pygame.draw.rect(scene, (100, 100, 100), grill_panel, 3)
        for i in range(3):
            pygame.draw.line(scene, (150, 150, 150),
                             (grill_panel.x, grill_panel.y + 20 + i*25),
                             (grill_panel.right, grill_panel.y + 20 + i*25), 2)
        for i in range(5):
            fx = grill_panel.x + 30 + i*45
            fy = grill_panel.y + 70 + int(math.sin(frame*0.15 + i) * 4)
            col = (240, 120, 40) if frame % 10 < 6 else (250, 180, 60)
            pygame.draw.circle(scene, col, (fx, fy), 4)
            pygame.draw.circle(scene, (250, 200, 100), (fx, fy), 2)

        screen.blit(scene, (0, 0))

        for c in customers:
            c.draw(screen)

        for i, r in enumerate(GRILL_RECTS):
            g = grill_slots[i]
            bg = (50, 45, 60) if g.is_empty() else (70, 50, 40)
            pygame.draw.rect(screen, bg, r)
            pygame.draw.rect(screen, C_PANEL_L, r, 2)
            gt = font_s.render(f"ГРИЛЬ #{i+1}", True, C_TEXT_DIM)
            screen.blit(gt, (r.x+8, r.y+6))
            if g.is_empty():
                pt = font_s.render("- пусто -", True, C_TEXT_DIM)
                screen.blit(pt, (r.centerx - pt.get_width()//2, r.centery - pt.get_height()//2))
            else:
                draw_food(screen, g.ing, r.x + 10, r.y + 20, 50, g.state)
                ct = COOK_TIME.get(g.ing, 4)
                bt = BURN_TIME.get(g.ing, 3)
                total = ct + bt
                bar = pygame.Rect(r.x + 70, r.y + 30, 120, 14)
                pygame.draw.rect(screen, (30,30,30), bar)
                if g.state == "raw":
                    pygame.draw.rect(screen, C_GOLD,
                                     (bar.x, bar.y, int(bar.w * min(1, g.time/ct)), bar.h))
                elif g.state == "cooked":
                    pygame.draw.rect(screen, C_GREEN, bar)
                else:
                    pygame.draw.rect(screen, C_RED, bar)
                pygame.draw.rect(screen, C_TEXT_DIM, bar, 2)
                st_txt = {"raw":"Сырое", "cooked":"Готово!", "burned":"СГОРЕЛО"}[g.state]
                st_col = {"raw":C_GOLD, "cooked":C_GREEN, "burned":C_RED}[g.state]
                ss = font_s.render(st_txt, True, st_col)
                screen.blit(ss, (r.x+70, r.y+50))
                if g.state == "cooked":
                    hint = font_xs.render("Клик — забрать", True, C_GREEN)
                    screen.blit(hint, (r.x+70, r.y+70))

        for r, ing in ing_rects:
            hover = r.collidepoint(mx, my)
            bg = (80, 65, 100) if hover else C_PANEL_D
            pygame.draw.rect(screen, bg, r)
            pygame.draw.rect(screen, C_GOLD if hover else C_TEXT_DIM, r, 2)
            draw_food(screen, ing, r.x+6, r.y+2, 60)
            nm = font_s.render(ING_SHORT[ing], True, C_TEXT)
            screen.blit(nm, (r.centerx - nm.get_width()//2, r.bottom - 18))

        top = pygame.Rect(0, 0, W, 40)
        pygame.draw.rect(screen, C_PANEL, top)
        day_s = font_m.render(f"ДЕНЬ {day}", True, C_GOLD)
        screen.blit(day_s, (20, 8))
        money_s = font_m.render(f"{game.money + earned}₽", True, C_GREEN)
        screen.blit(money_s, (150, 8))
        rep_s = font_m.render(f"Репутация: {game.reputation}", True, C_BLUE)
        screen.blit(rep_s, (300, 8))
        prog_s = font_m.render(
            f"Обслужено: {queue_served}/{total_customers}  Идеально: {queue_perfect}  Провалено: {queue_failed}",
            True, C_TEXT)
        screen.blit(prog_s, (520, 8))

        waiting = [c for c in customers if c.state == "waiting"]
        if waiting:
            c = waiting[0]
            nxt = c.order[len(current_order_ings)] if len(current_order_ings) < len(c.order) else None
            hint_rect = pygame.Rect(W//2 - 260, H - 170, 520, 56)
            pygame.draw.rect(screen, C_PANEL, hint_rect)
            pygame.draw.rect(screen, C_GOLD, hint_rect, 2)
            if nxt is not None:
                nm = ING_SHORT[nxt]
                ht = font_m.render(f"СЛЕДУЮЩИЙ: {nm}", True, C_GOLD)
            else:
                ht = font_m.render("ВСЁ ГОТОВО — отдать клиенту!", True, C_GREEN)
            screen.blit(ht, (hint_rect.centerx - ht.get_width()//2,
                             hint_rect.centery - ht.get_height()//2))

        if msg_t > 0:
            msg_t -= 1
            ms = font_m.render(msg, True, msg_col)
            msh = font_m.render(msg, True, (10,8,20))
            screen.blit(msh, (W//2 - ms.get_width()//2 + 2, 62))
            screen.blit(ms, (W//2 - ms.get_width()//2, 60))

        particles.update()
        particles.draw(screen)

        if (queue_served + queue_failed >= total_customers) and len(customers) == 0:
            if not day_ending:
                day_ending = True
                end_t = 1.5
        if day_ending:
            end_t -= dt
            if end_t <= 0:
                return earned, queue_served, queue_perfect, queue_failed

        pygame.display.flip()

    return earned, queue_served, queue_perfect, queue_failed

# ============================== ЗАПУСК ==============================
def run_week(start_day):
    for day in range(start_day, 8):
        if day in MORNING_SCRIPTS:
            run_dialogue(Dialogue(MORNING_SCRIPTS[day]))
        earned, served, perfect, failed = play_day(day)
        game.money += earned
        game.total_earned += earned
        game.failed += failed
        game.day = day + 1
        day_summary(day, earned, served, perfect, failed)
        if day < 7:
            if day in EVENING_SCRIPTS:
                run_dialogue(Dialogue(EVENING_SCRIPTS[day]))
            shop_screen()
            skills_screen()
        save_game()

    if game.reputation >= 60 and game.money >= 1500:
        run_dialogue(ending_good())
        game.ending = "good"
    elif game.reputation >= 30 or game.money >= 800:
        run_dialogue(ending_neutral())
        game.ending = "neutral"
    else:
        run_dialogue(ending_bad())
        game.ending = "bad"

def main():
    floats = [FloatingIng() for _ in range(18)]
    frame = 0
    while True:
        clock.tick(60)
        frame += 1
        rects = draw_main_menu(floats, frame)
        pygame.display.flip()
        mx, my = pygame.mouse.get_pos()
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                pygame.quit(); sys.exit()
            if e.type == pygame.MOUSEBUTTONDOWN and e.button == 1:
                for r, key, text in rects:
                    if r.collidepoint(mx, my):
                        if key == "new":
                            game.reset()
                            run_dialogue(script_intro())
                            run_week(1)
                        elif key == "continue":
                            if load_game():
                                run_week(game.day)
                        elif key == "about":
                            about_screen()
                        elif key == "exit":
                            pygame.quit(); sys.exit()

if __name__ == "__main__":
    try:
        main()
    except Exception:
        import traceback
        traceback.print_exc()
    finally:
        pygame.quit()