Deixe a interface mais compacta e bonita (use html no próprio script python)

```python
import csv
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
import requests
import json
import time
import websocket
import threading
import logging
from requests.exceptions import RequestException
from typing import Dict, Optional
import queue

logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(message)s')

opcoes = [
    "Dragon-Maior", "Dragon-Menor", "Tie-Menor",
    "Tiger-Maior", "Tiger-Menor", "SuitedTie-Menor"
]

def obter_evosessionid() -> Optional[str]:
    url_post = "https://blaze.com/api/games/dragon-tiger-evolution/play"
    headers = {
        "Host": "blaze.com",
        "Content-Type": "application/json;charset=UTF-8",
        "Authorization": "Bearer SUA_CHAVE_DE_AUTENTICAÇÃO_AQUI",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
        "Accept": "application/json, text/plain, */*",
        "Origin": "https://blaze.com",
        "Referer": "https://blaze.com/pt/games/dragon-tiger-evolution",
        "Accept-Language": "en-US,en;q=0.9,pt-BR;q=0.8,pt;q=0.7",
        "x-client-language": "pt",
        "x-client-version": "v2.2181.0",
    }
    payload = {"selected_currency_type": "BRL"}

    try:
        with requests.Session() as session:
            resposta = session.post(url_post, headers=headers, json=payload, timeout=30)
            resposta.raise_for_status()

            dados = resposta.json()
            url_ws = dados.get("url")

            if url_ws:
                time.sleep(1)
                headers_get = {
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
                    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9",
                    "Accept-Language": "en-US,en;q=0.9,pt-BR;q=0.8,pt;q=0.7",
                    "Referer": "https://blaze.com/",
                }
                resposta_get = session.get(url_ws, headers=headers_get, allow_redirects=True, timeout=30)
                resposta_get.raise_for_status()

                return session.cookies.get('EVOSESSIONID')
    except RequestException as e:
        logging.error(f"Erro ao obter EVOSESSIONID: {e}")
    return None

class DragonTigerWebSocket:
    def __init__(self, evosessionid: str, result_queue: queue.Queue):
        self.evosessionid = evosessionid
        self.apostas: Dict[str, int] = {"Dragon": 0, "Tiger": 0}
        self.url_ws = (
            f"wss://a8r.evo-games.com/public/dragontiger/player/game/DragonTiger00001/socket"
            f"?messageFormat=json&tableConfig=qfgyebpdhvchztoh&EVOSESSIONID={evosessionid}"
            f"&instance=ceurmi-pgkuwspw45weqgsa-qfgyebpdhvchztoh&client_version=6.20240927.72917.44963-240dc36920"
        )
        self.ws: Optional[websocket.WebSocketApp] = None
        self.thread: Optional[threading.Thread] = None
        self.result_queue = result_queue

    def on_message(self, ws: websocket.WebSocketApp, message: str) -> None:
        try:
            data = json.loads(message)
            if data.get('type') == 'dragontiger.bettingStats':
                self.apostas = {
                    "Dragon": data['args']['stats']['Dragon']['amount'],
                    "Tiger": data['args']['stats']['Tiger']['amount']
                }
            elif data.get('type') == 'dragontiger.resolved':
                vencedor = data['args']['result']['winner']
                comparacao = "Maior" if (
                    (vencedor == "Dragon" and self.apostas["Dragon"] > self.apostas["Tiger"]) or
                    (vencedor == "Tiger" and self.apostas["Tiger"] > self.apostas["Dragon"])
                ) else "Menor"
                resultado = f"{vencedor}-{comparacao}"
                logging.info(f"Resultado capturado: {resultado}")
                self.result_queue.put(resultado)
        except json.JSONDecodeError as e:
            logging.error(f"Erro ao decodificar JSON: {e}")
        except KeyError as e:
            logging.error(f"Erro ao acessar chave no dicionário: {e}")
        except Exception as e:
            logging.error(f"Erro ao processar a mensagem: {e}")

    def on_error(self, ws: websocket.WebSocketApp, error: Exception) -> None:
        logging.error(f"Erro na conexão WebSocket: {error}")

    def on_close(self, ws: websocket.WebSocketApp, close_status_code: Optional[int], close_msg: Optional[str]) -> None:
        logging.warning(f"Conexão WebSocket fechada: {close_status_code} - {close_msg}")

    def on_open(self, ws: websocket.WebSocketApp) -> None:
        logging.info("Conexão WebSocket estabelecida")

    def conectar(self) -> None:
        try:
            self.ws = websocket.WebSocketApp(
                self.url_ws,
                on_open=self.on_open,
                on_message=self.on_message,
                on_error=self.on_error,
                on_close=self.on_close
            )

            self.thread = threading.Thread(target=self.ws.run_forever, kwargs={'ping_interval': 60, 'ping_timeout': 10})
            self.thread.daemon = True
            self.thread.start()
            logging.info("Thread WebSocket iniciada")
        except Exception as e:
            logging.error(f"Erro ao conectar WebSocket: {e}")

    def parar(self) -> None:
        if self.ws:
            self.ws.close()
        if self.thread and self.thread.is_alive():
            self.thread.join()
        logging.info("WebSocket parado")

def start_websocket():
    while True:
        logging.info("Obtendo EVOSESSIONID...")
        evosessionid = obter_evosessionid()

        if evosessionid:
            logging.info("EVOSESSIONID válido obtido. Estabelecendo conexão WebSocket...")
            dragon_tiger_ws = DragonTigerWebSocket(evosessionid, result_queue)
            dragon_tiger_ws.conectar()
            if dragon_tiger_ws.thread:
                dragon_tiger_ws.thread.join()
            logging.info("Conexão WebSocket encerrada. Reconectando...")
        else:
            logging.error("Não foi possível obter um EVOSESSIONID válido. Tentando novamente em 30 segundos...")
            time.sleep(30)

def ler_csv(nome_arquivo):
    try:
        with open(nome_arquivo, 'r', encoding='utf-8') as arquivo:
            leitor = csv.reader(arquivo)
            resultados = []
            for linha in leitor:
                if linha:
                    resultados.append(linha[0].strip())
            return resultados
    except FileNotFoundError:
        logging.warning(f"Arquivo {nome_arquivo} não encontrado. Iniciando com lista de resultados vazia.")
        return []

def contar_sequencia(resultados, sequencia):
    contador = 0
    i = 0
    while i <= len(resultados) - len(sequencia):
        if resultados[i:i+len(sequencia)] == sequencia:
            contador += 1
            i += len(sequencia)
        else:
            i += 1
    return contador

def contar_proxima_previsao(resultados, sequencia):
    contagem = {opcao: 0 for opcao in opcoes}
    i = 0
    while i <= len(resultados) - len(sequencia) - 1:
        if resultados[i:i+len(sequencia)] == sequencia:
            proxima = resultados[i+len(sequencia)]
            if proxima in contagem:
                contagem[proxima] += 1
            i += len(sequencia)
        else:
            i += 1
    return contagem

resultados = ler_csv('resultados_dragon_tiger.csv')

sequencia_atual = []

def atualizar_sequencia(opcao):
    if len(sequencia_atual) >= max_sequencia_len:
        sequencia_atual.pop(0)
    sequencia_atual.append(opcao)
    atualizar_display_sequencia()
    atualizar_contagens()

def atualizar_display_sequencia():
    for widget in frame_sequencia_itens.winfo_children():
        widget.destroy()

    sequencia_label.config(text=f"Sequência atual ({len(sequencia_atual)}):")

    for idx, opcao in enumerate(sequencia_atual):
        btn = ttk.Button(frame_sequencia_itens, text=opcao, command=lambda idx=idx: remover_item_sequencia(idx), bootstyle="secondary", width=12)
        btn.pack(side=LEFT, padx=2, pady=2)

def remover_item_sequencia(idx):
    del sequencia_atual[idx]
    atualizar_display_sequencia()
    atualizar_contagens()

def atualizar_contagens():
    if sequencia_atual:
        contagem_seq = contar_sequencia(resultados, sequencia_atual)
        proxima_contagem = contar_proxima_previsao(resultados, sequencia_atual)
        
        contagem_dragon = sum(proxima_contagem.get(key, 0) for key in ['Dragon-Maior', 'Dragon-Menor'])
        contagem_tiger = sum(proxima_contagem.get(key, 0) for key in ['Tiger-Maior', 'Tiger-Menor'])
        
        frame_contagens.config(text=f"Contagens ({contagem_seq}) - Dragon ({contagem_dragon}) - Tiger ({contagem_tiger})")
        
        for item in treeview.get_children():
            treeview.delete(item)
        itens_ordenados = sorted(proxima_contagem.items(), key=lambda x: x[1], reverse=True)
        for opcao, contagem in itens_ordenados:
            treeview.insert("", "end", values=(opcao, contagem))
    else:
        frame_contagens.config(text="Contagens (0) - Dragon (0) - Tiger (0)")
        for item in treeview.get_children():
            treeview.delete(item)

def limpar_sequencia():
    sequencia_atual.clear()
    atualizar_display_sequencia()
    atualizar_contagens()

def desfazer():
    if sequencia_atual:
        sequencia_atual.pop()
        atualizar_display_sequencia()
        atualizar_contagens()

# Inicialização da janela principal com ttkbootstrap
janela = ttk.Window(themename="united")
janela.title("Análise de Sequências Dragon Tiger")
janela.geometry("800x600")
janela.resizable(True, True)

# Estilos personalizados
style = ttk.Style()
style.configure("TButton", font=("Arial", 10))
style.configure("TLabel", font=("Arial", 10))
style.configure("Treeview", font=("Arial", 10))
style.configure("Treeview.Heading", font=("Arial", 10, "bold"))

# Frame superior que combina opções e controles
frame_top = ttk.Frame(janela)
frame_top.pack(side=TOP, fill=X, padx=10, pady=5)

# Frame das opções
frame_opcoes = ttk.Labelframe(frame_top, text="Opções")
frame_opcoes.pack(side=LEFT, fill=X, expand=True)

# Botões de opções
for i, opcao in enumerate(opcoes):
    btn = ttk.Button(frame_opcoes, text=opcao, command=lambda o=opcao: atualizar_sequencia(o), bootstyle="primary", width=12)
    btn.grid(row=i//3, column=i%3, padx=2, pady=2)

frame_opcoes.grid_columnconfigure(0, weight=1)
frame_opcoes.grid_columnconfigure(1, weight=1)
frame_opcoes.grid_columnconfigure(2, weight=1)

# Frame dos controles
frame_controles = ttk.Labelframe(frame_top, text="Controles")
frame_controles.pack(side=LEFT, fill=Y, padx=(10,0))

ttk.Button(frame_controles, text="Limpar", command=limpar_sequencia, bootstyle="danger", width=10).pack(padx=5, pady=5)
ttk.Button(frame_controles, text="Desfazer", command=desfazer, bootstyle="warning", width=10).pack(padx=5, pady=5)

# Configuração do tamanho máximo da sequência
max_seq_len_var = ttk.IntVar(value=6)
max_sequencia_len = max_seq_len_var.get()

def on_max_seq_len_change(*args):
    global max_sequencia_len
    try:
        max_sequencia_len = max_seq_len_var.get()
        if max_sequencia_len <= 0:
            max_sequencia_len = 1
            max_seq_len_var.set(1)
        while len(sequencia_atual) > max_sequencia_len:
            sequencia_atual.pop(0)
        atualizar_display_sequencia()
        atualizar_contagens()
    except ttk.TclError:
        pass

max_seq_len_var.trace_add('write', on_max_seq_len_change)

# Frame da sequência
frame_sequencia = ttk.Labelframe(janela, text="Sequência")
frame_sequencia.pack(fill=X, padx=10, pady=5)

frame_sequencia_top = ttk.Frame(frame_sequencia)
frame_sequencia_top.pack(fill='x', padx=5, pady=(5,0))

sequencia_label = ttk.Label(frame_sequencia_top, text="Sequência atual (0):", font=("Arial", 10, "bold"))
sequencia_label.pack(side=LEFT, padx=(0,5))

ttk.Label(frame_sequencia_top, text="Tamanho Máx:", font=("Arial", 10)).pack(side=LEFT, padx=(10,5))

max_seq_len_entry = ttk.Entry(frame_sequencia_top, textvariable=max_seq_len_var, width=5)
max_seq_len_entry.pack(side=LEFT)

frame_sequencia_itens = ttk.Frame(frame_sequencia)
frame_sequencia_itens.pack(fill="x", padx=5, pady=5)

# Frame das contagens
frame_contagens = ttk.Labelframe(janela, text="Contagens (0)")
frame_contagens.pack(fill=BOTH, expand=True, padx=10, pady=(5,10))

# Treeview para exibir contagens
treeview = ttk.Treeview(frame_contagens, columns=("Opção", "Contagem"), show="headings", bootstyle="info")
treeview.heading("Opção", text="Opção")
treeview.heading("Contagem", text="Contagem")
treeview.column("Opção", width=200, anchor="center")
treeview.column("Contagem", width=100, anchor="center")
treeview.pack(side=LEFT, fill=BOTH, expand=True, padx=5, pady=5)

scrollbar_treeview = ttk.Scrollbar(frame_contagens, orient=VERTICAL, command=treeview.yview)
treeview.configure(yscrollcommand=scrollbar_treeview.set)
scrollbar_treeview.pack(side=LEFT, fill=Y, pady=5)

# Função para verificar novos resultados
result_queue = queue.Queue()

def check_new_results():
    try:
        while True:
            result = result_queue.get_nowait()
            resultados.append(result)
            logging.info(f"Novo resultado recebido: {result}")
            atualizar_sequencia(result)
    except queue.Empty:
        pass
    janela.after(1000, check_new_results)

# Iniciar thread do WebSocket
websocket_thread = threading.Thread(target=start_websocket)
websocket_thread.daemon = True
websocket_thread.start()

check_new_results()

janela.mainloop()
```